Reusing a verified Mock
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.开发者_JAVA百科 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?
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)
Short answer: yes
Longer answer: Try the following
[Test]
public void RhinoMock_PerformMultipleChecks()
{
var myMock = MockRepository.GenerateDynamicMockWithRemoting<IComparable>();
// first round of checks
myMock.Expect(x => x.CompareTo("123")).Return(1);
myMock.Expect(x => x.CompareTo("-12")).Return(-1);
Assert.AreEqual(1, myMock.CompareTo("123"));
Assert.AreEqual(-1, myMock.CompareTo("-12"));
myMock.VerifyAllExpectations();
// reset
myMock.BackToRecord();
myMock.Replay();
// next round of checks
myMock.Expect(x => x.CompareTo(1.23)).Return(1);
myMock.Expect(x => x.CompareTo(-12)).Return(-1);
Assert.AreEqual(1, myMock.CompareTo(1.23));
Assert.AreEqual(-1, myMock.CompareTo(-12));
myMock.VerifyAllExpectations();
// reset
myMock.BackToRecord();
myMock.Replay();
// final round of checks
myMock.Expect(x => x.CompareTo(1.23m)).Return(1);
myMock.Expect(x => x.CompareTo(-12m)).Return(-111);
Assert.AreEqual(1, myMock.CompareTo(1.23m));
Assert.AreEqual(-111, myMock.CompareTo(-12m));
myMock.VerifyAllExpectations();
}
精彩评论