Why another mock framework?

FluentSpec was announced as a BDD framework trying to avoid mock controversy, in particular the one caused by test doubles. But a Mock is both, a test double and a development practice, so there’s no way to avoid the term. And BDD is mainly a communication practice that goes far beyond using the GWT syntax to write unit tests. FluentSpec is better described as a mock framework with a BDD flavor.

There are multiple mock frameworks in C#: RhinoMocks, Moq, NMocks and TypeMock. I started with NMocks and switched to Rhino. At that moment the main reason for the switch was that NMock was using literals to setup calls. RhinoMocks kept me happy until my style of development required more isolation of the SUT. Isolation is the specialty of TypeMock, but I think it goes too far allowing the usage of Band-Aids in places where we should stitch.

My conflict with RhinoMock can be expressed with this test

    [TestClass]
    public class when_defining_a_complex_method {
        
        [TestMethod]
        public void should_split_in_simpler_methods() {
            
            var Mocks = new MockRepository();
            var Subject = Mocks.PartialMock<Subject>();
            Mocks.ReplayAll();
            
            Subject.ComplexMethod();
            
            Subject.AssertWasCalled(x => x.DoASimpleMethod());
            Subject.AssertWasCalled(x => x.DoAnotherSimpleMethod());
        }
    }

    public class Subject {
    
        public void ComplexMethod() {
            DoASimpleMethod();
            DoAnotherSimpleMethod(); 
        }

        public virtual void DoASimpleMethod() {
            throw new System.NotImplementedException();
        }

        public virtual void DoAnotherSimpleMethod() {
            throw new System.NotImplementedException();
        }
    }

This test throws System.NotImplementedException() which might be really easy to fix by removing that line. However, in terms of isolation it implies that when I wanted to test only the ComplexMethod I also ran the other depended methods. Running the depended methods might lead to a failure at another level of abstraction. It could be possible to abstract that call in a dependency. But then I would not need a PartialMock and I would not be ripping the full benefits of the Composed Method pattern.

The test could be written in FluentSpec and would pass despite the throw clause.

    [TestClass]
    public class when_defining_a_complex_method : BehaviorOf<Subject> {
        
        [TestMethod]
        public void should_split_in_simpler_methods() {
            
            When.ComplexMethod();
            Should.DoASimpleMethod();
            Should.DoAnotherSimpleMethod();
        }
    }

That is in essence the reason why I needed another mock framework and why I could not wrap it around an existing one. The other reasons are also shown in this example.
  • Simplifies test setup
    var Mocks = new MockRepository();
    var Subject = Mocks.PartialMock<Subject>();
    Mocks.ReplayAll();

    BehaviorOf<Subject> 
* Doesn’t have test doubles like Stub, Mock or PartialMock. It has only a TestObject.
  • Avoids repetitions of SUT references like
    Subject.ComplexMethod();
    Subject.AssertWasCalled(x => x.DoASimpleMethod());
    Subject.AssertWasCalled(x => x.DoAnotherSimpleMethod());

    When.ComplexMethod();
    Should.DoASimpleMethod();
    Should.DoAnotherSimpleMethod(); 
* And doesn’t need lambdas or delegates to setup and verify calls.

Last edited Jan 24, 2009 at 3:16 PM by mikemps, version 7

Comments

No comments yet.