views:

250

answers:

3

Say I have an interface IFoo which I am mocking. There are 3 methods on this interface. I need to test that the system under test calls at least one of the three methods. I don't care how many times, or with what arguments it does call, but the case where it ignores all the methods and does not touch the IFoo mock is the failure case.

I've been looking through the Expect.Call documentation but can't see an easy way to do it.

Any ideas?

+1  A: 

You can give rhino mocks a lambda to run when a function get's called. This lambda can then increment a counter. Assert the counter > 1 and you're done.

Commented by Don Kirkby: I believe Mendelt is referring to the Do method.

Mendelt
I believe Mendelt is referring to the Do method.
Don Kirkby
Thanks for the useful comment to my too short answer. Added it to the question.
Mendelt
A: 

Not sure this answers your question but I've found that if I need to do anything like that with Rhino (or any similiar framework/library), anything that I didn't know how to do upfront, then I'm better just creating a manual mock.

Creating a class that implements the interface and sets a public boolean field to true if any of the methods is called will be trivially easy, you can give the class a descriptive name which means that (most importantly) the next person viewing the code will immediately understand it.

A: 

If I understood you correctly you want to check that the interface is called at least once on any of three specified methods. Looking through the quick reference I don't think you can do that in Rhino Mocks.

Intuitively I think you're trying to write a test that is brittle, which is a bad thing. This implies incomplete specification of the class under test. I urge you to think the design through so that the class under test and the test can have a known behavior.

However, to be useful with an example, you could always do it like this (but don't).

[TestFixture]
public class MyTest {

    // The mocked interface
    public class MockedInterface implements MyInterface {
       int counter = 0;
       public method1() { counter++; }
       public method2() { counter++; }
       public method3() { counter++; }
    }

    // The actual test, I assume you have the ClassUnderTest
    // inject the interface through the constructor and
    // the methodToTest calls either of the three methods on 
    // the interface.
    [TestMethod]
    public void testCallingAnyOfTheThreeMethods() {
        MockedInterface mockery = new MockedInterface();
        ClassUnderTest classToTest = new ClassUnderTest(mockery);

        classToTest.methodToTest();

        Assert.That(mockery.counter, Is.GreaterThan(1));
    }
}

(Somebody check my code, I've written this from my head now and haven't written a C# stuff for about a year now)

I'm interested to know why you're doing this though.

Spoike
One error : class MockedInterface must expose publicly the counter field. Written as it is it's just a private field.
Andrei Rinea
@Andrei Rinea: Actually MyTest knows all the internals of MockedInterface because it is an inner class. I was surprised when I noticed that I accidentally made a private field in the inner class but found out it was still accessible by the outer class.
Spoike