Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Rhino.Mocks AssertWasCalled() correctly?

I call _mocks.ReplayAll(), then one or more _mockedObject.AssertWasCalled() and then _mocks.VerifyAll(). But it tells me that "This action is invalid when the mock object is in record state".

[Test]
public void SetStateExecuting_Should_Set_State_To_Pause_And_Not_Change_GlobalState_When_GlobalState_Is_Paused()
{
    var task = new Task { ID = 1, TimeZone = -660, GlobalState = TaskState.Paused };
    _taskDataProvider.Expect(p => p.StateUpdate(task.ID, task.TimeZone, TaskState.Paused));
    _mockRepository.ReplayAll();
    _manager.SetStateExecuting(task);
    _taskDataProvider.AssertWasNotCalled(p => p.GlobalStateUpdate(task.ID, 
                                                                  TaskState.Executing));
    _mockRepository.VerifyAll();
}

What is the correct order to call so that these methods work correctly?

like image 923
HiveHicks Avatar asked Jun 25 '10 09:06

HiveHicks


People also ask

What is the use of Rhino mock?

Rhino Mocks is open source framework and released under the BSD license. Rhino Mocks works on Arrange, Act and Assert (AAA) pattern. Rhino Mocks allows both State verification and Behavior verification of objects. Rhino Mocks can not mock static and sealed methods of a class.

Why is verifyallexpectations not working on my Rhino stubs?

In Rhino Mocks, expectations on stubs are not verified; only mocks are verified. If an object is created with GenerateStub instead of GenerateMock, then its VerifyAllExpectations method doesn't do anything. This is non-obvious because the AssertWasCalled and AssertWasNotCalled methods on a stub will behave the way you want them to.

What happens if a method is not provided in a mock?

If any methods/properties are used which you have not provided implementations for, an exception will be thrown. Dynamic Mock. With a dynamic mock, any methods/properties which are called by your tests for which you have not provided an implementation will return the default value for the data type of the return value.

Should I use assertwascalled() or replayall() in a static method?

If aren’t using the static methods (or are using something like StructureMap’s RhinoAutoMocker where the mocks are created for you), you can still utilize AssertWasCalled as long as you call ReplayAll () before the “act” phase of your test.


2 Answers

Jon Kruger's blog post "How to use rhino mocks documented through tests" has simple examples of everything you can do with rhino mocks methods. He also shows what you can not do which I found very helpful in learning.

As mentioned before, using the Arrange, Act, Assert Syntax with the static constructors is easier to read. The blog post shows examples of both methods.

Here are examples from Jon's sample code:

New syntax:

 [Test]
    public void You_can_check_to_see_if_a_method_was_called()
    {
        var stub = MockRepository.GenerateStub<ISampleClass>();

        stub.MethodThatReturnsInteger("foo");

        stub.AssertWasCalled(s => s.MethodThatReturnsInteger("foo"));
        stub.AssertWasCalled(s => s.MethodThatReturnsInteger(Arg<string>.Is.Anything));
    }

Old style:

    [Test]
    public void Calling_virtual_methods_will_call_the_actual_method()
    {
        var mockRepository = new MockRepository();
        var sampleClass = mockRepository.PartialMock<SampleClass>();
        sampleClass.Replay();

        sampleClass.VirtualMethod("foo").ShouldEqual(3);
        sampleClass.VirtualMethodWasCalled.ShouldBeTrue();
        sampleClass.AssertWasCalled(c => c.VirtualMethod("foo"));
    }
like image 84
Maggie Avatar answered Oct 07 '22 16:10

Maggie


You are mixing the old Record/Replay pattern and the new AAA pattern.

The normal way to set up a "not called with these arguments" expectation while in Record mode looks like this:

_taskDataProvider.Expect(
    p => p.GlobalStateUpdate(task.ID, TaskState.Executing)).Repeat.Never();

Or alternatively, you can use a strict mock which simply doesn't allow unexpected calls.

AssertWasCalled and AssertWasNotCalled are intended for AAA where you put your assertions at the end. With the Record/Replay syntax, both behavior and expecations should be set up at the start before the switch to replay mode.

(AssertWasNotCalled might actually work with Record/Replay also, but I never tried it because I don't like to mix elements from both approaches. It needlessly complicates things.)

like image 37
Wim Coenen Avatar answered Oct 07 '22 14:10

Wim Coenen