views:

98

answers:

2

I use RhinoMocks for a very simple test (I have to say I'm a beginner here). I tried to mock my object like this

var mock = MockRepository.GenerateMock<MyClass>();

create a helper stub :

var stubLinkedObject = MockRepository.GenerateStub<MyClass>();

then execute some logic which should call the method AddLink of the class MyClass with my stub argument. At the end of the test I simply assert that this method was actually called with

mockAction.AssertWasCalled(a => a.AddLink(stubLinkedObject));

I injected the correct dependency and the method is actually called. However, the problem is that the real implementation in MyClass is called and results in crash because some logic just can't be executed (link collection is not available etc.). How can I bypass the execution and simply check whether a method is called ? I have tried something like

mockAction.Stub(a => a.AddLink(null)).IgnoreArguments().Do(null);

before I go into the execution but this doesn't seem to work(I only get some exceptions). Any ideas and probably an explanation why the mock is executing the method logic at all ?

+4  A: 

I've tried to reproduce. Here is the code which works fine for me

[Test]
public void Test()
{
    var classMock = MockRepository.GenerateMock<MyClass>();
    var linkedMock = MockRepository.GenerateStub<MyClass>();

    classMock.Expect(c => c.MyMethod(linkedMock));

    classMock.MyMethod(linkedMock);

    classMock.AssertWasCalled(c => c.MyMethod(linkedMock));
}

public class MyClass
{
    public virtual void MyMethod(MyClass linkedClass)
    {
        Console.WriteLine("MyMethod is called");
    }
}
dh
That would probably work. Thanks ;)
Thomas Wanner
Like the question, this answer confuses me. You're mixing `Expect` (used for the record phase in record-replay-verify) with `AssertWasCalled` (used in the assert phase in arrange-act-assert). You should not mix both approaches in the same test.
Wim Coenen
That's a new mode of mocking using Rhino Mocks 3.5. Mocks/stubs returned from MockRepository.GenerateMock() and MockRepository.GenerateStub() are returned in replay mode, and do not require explicit move to replay mode. Have a look here http://www.ayende.com/Wiki/Rhino+Mocks+3.5.ashx#MockingwithandwithoutaninstanceofMockRepository
dh
I think wcoenen is right, you should either use `Expect` then call `VerifyAllExpectations` or you should just `AssertWasCalled`. Nowhere in the link that you provided does it `Expect` without also `VerifyAllExpectations` or `Expect` and `AssertWasCalled` on the same thing.
Sam Holder
In that same help you can find a description for Expect() extension method where it is said that "The Expect() extension method creates a new expectation for this mock which must be verified/asserted later (using either the VerifyAllExpectations() or AssertWasCalled() methods)." So it does not matter actually which one you choose (here: http://www.ayende.com/Wiki/Rhino+Mocks+3.5.ashx#ExpectExtensionMethod)
dh
At the same time I agree that expectation seems to be redundant as not providing any additional value to the test in the light of assertion
dh
+2  A: 

Your approach will only work if your method AddLink is virtual, otherwise the .Net runtime will always run the real implementation (and rightly so).

Usually the best practise is to use interfaces when doing dependency injection (so your class expects IMyClass instead of MyClass). This way it is much easier to use mocking frameworks - not only you don't have to remember to make all methods virtual, but you avoid the issues with passing correct arguments to MyClass's constructor (which in real world is a pain)

Grzenio