# Need help with FlexMock (or mocking in general)

**URL:** <https://www.ruby-forum.com/t/need-help-with-flexmock-or-mocking-in-general/95874>\
**Category:** Ruby\
**Created:** [June 16, 2006, 10:54pm UTC](https://www.ruby-forum.com/t/need-help-with-flexmock-or-mocking-in-general/95874 "2006-06-16T22:54:12Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [June 16, 2006, 10:54pm UTC](https://www.ruby-forum.com/t/need-help-with-flexmock-or-mocking-in-general/95874/1 "2006-06-16T22:54:12Z")

</div>

I’m trying to mock a single method call in a controller I’m testing  
(this isn’t a Rails question). I only want to mock the method for  
certain tests while the “real” method continues to function as before  
in the remainder of the tests. I’m trying to figure out how to use  
FlexMock to do this but I’m coming up empty.

Here’s some example code showing what I’m trying to do, and what I’d  
like to mock.

require ‘rubygems’  
require ‘uuid’

class StorageController  
def get\_next\_uuid  
UUID.new  
end

def assign\_uuid  
3.times do |attempt|  
uuid = get\_next\_uuid  
return [uuid] if not @records.include?(uuid)  
end  
[“Too many uuid collisions”]  
end  
end

And now for the tests…

class StorageControllerApiTest \< Test::Unit::TestCase  
include FlexMock::TestCase

def test\_assign\_uuid  
# this call should use the real #get\_next\_uuid or real #UUID.new  
methods  
result = @controller.assign\_uuid  
assert\_equal 0, result[0] =~ /^([a-z\d]+)-([a-z\d]+)-([a-z\d]+)  
-([a-z\d]+)-([a-z\d]+)$/

```
 # want to mock #get_next_uuid or #UUID.new here! Want to mock it

```

out so I can force  
# the #assign\_uuid method to “fail” and returns the error message  
result = @controller.assign\_uuid  
assert\_equal 0, result[0] =~ /^Too many uuid collisions$/  
end  
end

So how do I mock out either #get\_next\_uuid or UUID.new? I thought  
mocking UUID.new would be easiest but I can’t see how to use FlexMock  
to handle the case where there are no instance methods and only class  
methos (that is, you don’t call UUID.new to get an instance of the  
UUID class, it just returns a value directly).

I asked a similar question on the Rails list but it occurred to me  
this is primarily a question about mocks. I’d like to get better at  
creating and using them within my tests.

Thanks for the help!

cr

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [June 17, 2006, 3:58pm UTC](https://www.ruby-forum.com/t/need-help-with-flexmock-or-mocking-in-general/95874/2 "2006-06-17T15:58:19Z")

</div>

On Jun 16, 2006, at 9:31 PM, Jim W. wrote:

> Controller/UUID interaction.  
> Absolutely true.

> ```
> end
> 
> ```
> 
> end
> 
> (There are several ways of doing this, this is just an ad hoc way that  
> is simple for one-off situations. If you find yourself doing this a  
> lot, then you might want to consider a dependency injection  
> framework).

A dependency injection framework? Mmmm… getting a bit beyond my  
knowledge and experience. Though, come to think of it, I do recall  
running across a write-up of using a dependency injection framework  
in Rails instead of the existing Test::Unit stuff. I didn’t read the  
whole paper… I should google for that again. I may need this  
capability somewhere down the road.

> Now, write the tests. I would start off like this:
> 
> class TestStorageControllerUuidInteractionTest \<  
> Test::Unit::TestCase  
> include FlexMock::TestCase
> 
> ```
> def setup
> @controller = StorageController.new
> @controller.uuid_class = flexmock("uuid")
> end
> 
> ```

This all worked. I had to change “@controller.uuid\_class=” to  
“@controller.test\_uuid=” to match the previous accessor setup, but  
otherwise this all worked right out of the box. Amazing stuff. Every  
day I learn something new about the dynamism of Ruby.

> [snip]  
> That covers the tests in your example. There are a couple more  
> tests I  
> would suggest: (a) Mulitple UUID requests returning different values,  
> (b) cause a UUID colision, but not so many that the assign fails. But  
> that’s enough for this message.

Now that I have the base tests working, I will do as you suggest.

> Does this help?

Does it ever! When I posted this message I purposefully put  
“FlexMock” into the title in the hope that you (as the author of it)  
would notice and answer the question. Thanks very much for doing so!

The Flexmock documentation examples didn’t cover the case where a  
class mocked just a single method which is why I was floundering a  
bit here. After I experiment a bit more and wrap my head around how  
this is working, I hope you’ll accept a documentation patch that  
illustrates this.

cr

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [June 17, 2006, 4:31am UTC](https://www.ruby-forum.com/t/need-help-with-flexmock-or-mocking-in-general/95874/3 "2006-06-17T04:31:23Z")

</div>

unknown wrote:

> I’m trying to mock a single method call in a controller I’m testing  
> (this isn’t a Rails question). I only want to mock the method for  
> certain tests while the “real” method continues to function as before  
> in the remainder of the tests. I’m trying to figure out how to use  
> FlexMock to do this but I’m coming up empty.

The first step is to decide what you are testing. Are you testing the  
controller, or the UUID class? In this case, it looks like it is the  
controller. In fact, it looks like you are specifically testing the  
Controller/UUID interaction.

So, I would recommend something like this. First, write your controller  
as you would normally do:

class StorageController  
def get\_next\_uuid  
UUID.new  
end  
def assign\_uuid  
# blah, blah, blah … more code  
end  
end

Now, in your test file, cleverly modify the Storage controller class to  
allow you to inject a mock UUID:

class StorageController  
attr\_accessor :test\_uuid  
def get\_next\_uuid  
(@test\_uuid || UUID).new  
end  
end

(There are several ways of doing this, this is just an ad hoc way that  
is simple for one-off situations. If you find yourself doing this a  
lot, then you might want to consider a dependency injection framework).

Now, write the tests. I would start off like this:

class TestStorageControllerUuidInteractionTest \< Test::Unit::TestCase  
include FlexMock::TestCase

```
def setup
  @controller = StorageController.new
  @controller.uuid_class = flexmock("uuid")
end

```

[…]

Notice the name of the test. We are not testing the entire  
StorageController API, just the UUID interaction. That allows us to  
have a setup that creates the controller and injects our mock UUID.

Now, the first test. Let’s make sure the controller can handle assign a  
simploe UUID.

```
def test_controller_assigns_uuid
  @controller.uuid_class.
    should_receive(:new).once.and_return('a-a-a-a-a')
  assert_equal ['a-a-a-a-a'],
    @controller.assign_uuid
end

```

We tell the mock it will be called once and will return a fixed value.  
We then make sure the value is returned.

Ok, next test. Let’s make sure the controller correctly handles UUID  
collisions. We will setup our UUID to expect to be called 4 times (once  
for the initial uuid, and then 3 times during collision retry loop).

```
def test_controller_handles_excessive_uuid_collisions
  @controller.uuid_class.
    should_receive(:new).times(4).and_return('a-a-a-a-a')
  @controller.assign_uuid
  assert_equal ['Too many uuid collisions'],
    @controller.assign_uuid
end

```

That covers the tests in your example. There are a couple more tests I  
would suggest: (a) Mulitple UUID requests returning different values,  
(b) cause a UUID colision, but not so many that the assign fails. But  
that’s enough for this message.

Does this help?

– Jim W.
