unit testing

.NET Musings

Wandering thoughts of a developer, architect, speaker, and trainer

NAVIGATION - SEARCH

Verifying the Order Of Method Execution With Rhino Mocks 3.5

A question came up on twitter today about verifying the order of execution for methods on a class. My initial tweet back was simple. "Use Rhino Mocks".  I have created countless ordered tests in the earlier versions of Rhino Mocks, and didn't give it much of a thought. 

Then it occurred to me that I have not done this yet with the new AAA syntax.  This ended up being a bit more involved than I had thought. Still very do-able, but as far as I can tell, it can't be done entirely in the new fluent style.

I needed to setup two tests for this, as I am really testing Rhino Mocks and not my class at this point.  I needed to have one test the set the expectations up in the correct order (and would pass), and another that set them up in the incorrect order (and would throw an exception). 

For brevity, I have both tests listed here:

[Test]
public void Should_Call_Method_1_Then_Method_2()
{
    var mocks = new MockRepository();
    var foo = mocks.DynamicMock<IFoo>();
    using (mocks.Ordered())
    {
        foo.Expect(x => x.Method1());
        foo.Expect(x => x.Method2());
    }
    foo.Replay();
    var bar = new Bar(foo);
    bar.DoWork();
    foo.VerifyAllExpectations();
}
[Test]
public void Should_Fail_on_Calling_Method_2_Then_Method_1()
{
    var mocks = new MockRepository();
    var foo = mocks.DynamicMock<IFoo>();
    using (mocks.Ordered())
    {
        foo.Expect(x => x.Method2());
        foo.Expect(x => x.Method1());
    }
    foo.Replay();
    var bar = new Bar(foo);
    bar.DoWork();
    Assert.Throws<ExpectationViolationException>(() => foo.VerifyAllExpectations());
}

 

For ordered tests, you have to instantiate a MockRepository (you can't use the static methods for the AAA syntax).  You then setup your expectations on your mock object within an Ordered using block (this is the same process as the old Record block).  After you have setup the proper expectations, you have to put the mock object into "Play" mode with foo.Replay().  The next step is to make the call to the container object that calls the Interface methods, and then finish it all off with a call to foo.VerifyAllExpectations().  You can see that we do get to take advantage of some of the plumbing that was created for the AAA syntax, so it is indeed cleaner than the pre-3.5 version of the same tests. 

 

For the test I have as the System Under Test an Interface that has two methods (no need for a real implementation since it's going to be mocked anyway), and a single class that takes the Interface as a constructor parameter, and has one public method that calls the two methods on the interface.

public interface IFoo
{
    void Method1();
    void Method2();
}
public class Bar
{
    private readonly IFoo _foo;
    public Bar(IFoo foo)
    {
        _foo = foo;
    }
    public void DoWork()
    {
        _foo.Method1();
        _foo.Method2();
    }
}

Happy Coding!

Managed Windows Shared Hosting by OrcsWeb