tags:

views:

23

answers:

1

I am doing ordered expectations in rhino mocks as described by ayende in this post. My code looks something like this:

using (_mocks.Ordered())
  {
    Expect.Call(() => _myMock.CallA());
    Expect.Call(() => _myMock.CallB(40));
    Expect.Call(() => _myMock.CallA());
  }
  _mocks.ReplayAll();
  _myObjectUnderTest.DoStuff();
  _mocks.VerifyAll();

After this I would like to add more expectations and test more of my object's methods. I want to do this because I have some basic test methods that do some setup on my test object, and I do not want to have to retest that functionality, so I just call the earlier test method. If I try and add more expectations after VerifyAll() I get an exception: "This action is invalid when the mock object is in verified state."

Part of my problem is that I don't really understand what all of the replay/verify stuff is doing, I just copied code. I am using strict mocks, so any setup code must have matching expectations or it fails. I do not want to duplicate the expectations for my setup code.

Is there a way to reset the mock to be ready to start over in some way?

+2  A: 

Short answer: no. Now on to the long answer.

What the replay and verify stuff does is this. Before you call ReplayAll, you are telling Rhino what you expect the methods are going to do. You in a sense are recording calls to the mock objects you've created.

After you've recorded the method calls, you call ReplayAll telling Rhino you're now going to do 'something' that should execute the methods as recorded.

Last, you call VerifyAll asking Rhino to verify whether the methods were actually called as you've recorded them.

Now on to why you really should not want to re-use the mocks. With unit testing/TDD, your unit test should test as little as possible. This is to keep your unit tests simple and transparent. The whole idea of unit testing is that many many many small tests as a whole test the entire system.

For a very good presentation on TDD explaining this and other subjects, see http://www.infoq.com/presentations/integration-tests-scam.

P.S.: One small detail: As long as the methods don't return a result, you can write:

using (_mocks.Ordered())
{
    Expect.Call(() => _myMock.CallA());
    Expect.Call(() => _myMock.CallB(40));
    Expect.Call(() => _myMock.CallA());
}

as:

using (_mocks.Ordered())
{
    _myMock.CallA();
    _myMock.CallB(40);
    _myMock.CallA());
}

(at least with the latest version of Rhino)

Pieter
The problem comes when I want to test B, but A must be called in order to set everything up for B first. If A calls methods on my mock then I must expect them or else use dynamic mocks instead of strict ones. I would like to not duplicate all of the expectations, because I have already thoroughly tested A.
CaptnCraig
Yep, I've got that problem too. You have two options. The first is to modify your business logic so that you can either control what parts are triggered, or you split up your business logic into smaller parts you test independently. The second option is to lift some expectations into a private method of your `[TestFixture]` and call that in both tests. I did the last one (for now).
Pieter