5

How can I verify a mock is called in the "act" portion of my test ignoring any calls to the mock in the "arrange" portion of the test.

[Test]
public void ShouldOpenThrottleWhenDrivingHome()
{
    var engineMock = MockRepository.GenerateStub<IEngine>();
    var car = new Car(engineMock);
    car.DriveToGroceryStore(); // this will call engine.OpenThrottle

    car.DriveHome();

    engine.AssertWasCalled(e => e.OpenThrottle());
}

I'd prefer not to try an inject a fresh mock or rely on .Repeat() because the test then has to know how many times the method is called in the setup.

Gene C
  • 2,010
  • 26
  • 34
Brian Low
  • 11,605
  • 4
  • 58
  • 63
  • 1
    This one was already asked: http://stackoverflow.com/questions/770013/rhino-mocks-how-to-clear-previous-expectations-on-an-object – Amittai Shapira Oct 14 '11 at 20:21
  • I've read the question again - it's probably not a duplicate, but I'm not sure what is exactly the question. What does ClearStub() should do? Where were the stubs initialized? – Amittai Shapira Oct 14 '11 at 20:38
  • Yeah, that is not a duplciate. I've edited the question, hopefully it is clearer. – Brian Low Oct 15 '11 at 19:26
  • Thank you, much clearer now... – Amittai Shapira Oct 16 '11 at 19:54
  • Aww... all these answers require using expert/verify. Wish there was a purely AAA way to do this. I'd actually like to be able to use .Repeat()... except reset the calls at a particular point (right before my Act). I use constructor injection so giving my SUT a new mock won't work. – Jeff B Feb 20 '12 at 14:32

2 Answers2

5

In these situations I use a mock instead of a stub and combination of Expect and VerifyAllExpectations:

//Arrange
var engineMock = MockRepository.GenerateMock<IEngine>();
var car = new Car(engineMock);
car.DriveToGroceryStore(); // this will call engine.OpenThrottle

engineMock.Expect(e => e.OpenThrottle());

//Act
car.DriveHome();

//Assert
engineMock.VerifyAllExpectations();

In this case the expectation is placed on the method after the arranging is complete. Sometimes I think of this as its own testing style: Arrange, Expect, Act, Assert

Gene C
  • 2,010
  • 26
  • 34
2

I've reread your question and it seems that you want some method to seperate between the calls to the mock during the Arrange stage, and the calls to the mock during the Act stage. I don't know of any built-in support for it, but what you can do is pass a callback by using WhenCalled. In your case the code would be something like:

// Arrange
var engineMock = MockRepository.GenerateStub<IEngine>();
var car = new Car(engineMock);
int openThrotlleCount = 0;
engineMock.Expect(x => x.OpenThrottle(arg)).WhenCalled(invocation => openThrotlleCount++);
car.DriveToGroceryStore(); // this will call engine.OpenThrottle
var openThrottleCountBeforeAct = openThrotlleCount;

// Act
car.DriveHome();

// Assert
Assert.Greater(openThrotlleCount, openThrottleCountBeforeAct);

Hope it helps...

Amittai Shapira
  • 3,749
  • 1
  • 30
  • 54