From: Jim Weirich Date: 2006-06-17T11:31:41+09:00 Subject: Re: need help with FlexMock (or mocking in general) 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 Weirich -- Posted via http://www.ruby-forum.com/.