This documentation applies to NMock 1.x and is no longer being maintained.

NMock is a dynamic mock-object library for .NET. Its purpose is to provide a clean API for rapidly creating mock implementations of custom objects and verifying that objects interact with them correctly from unit tests.

A mock:

Features specific to NMock:

Basics

A simple example which demonstrates some of the features of NMock:

    class ClassUnderTest { // the class under test.

        public Something something; // an external object.

        public ClassUnderTest( Something something ) {
            this.something = something;
        }

        // method under test.
        public void DoYourStuff() {

            if ( someComplicatedLogic() ) {
            something.Eat( "cheese", 22, true ); // interaction with external object.
            }
            else {
            something.Nap(); // another interaction
            }
        }
    }


    // class that's to be mocked. Note that methods are virtual.
    // the implementations of these methods are not called during the test as they are mocked out.
    class Something {

        public virtual void Eat( string food, int numChews, bool eatWithMouthClosed ) {
        ...
        }

        public virtual void Nap() {
        ...
        }
    }


    [ Test ]
    public void SomethingTest() {

        // SETUP
        Mock mock = new DynamicMock(typeof(Something)); // create a mock
        ClassUnderTest classUnderTest = new ClassUnderTest((Something)mock.MockInstance);
        // pass mock into ClassUnderTest.
        // note that you get the mocked instance by calling Mock.MockInstance and casting.

        // EXPECTATIONS : how we expect the ClassUnderTest to deal with mock.
        mock.Expect("Eat", new IsEqual("cheese"), new IsAnything(), new IsAnything()); // see below
        mock.ExpectNotCalled("Nap");

        // EXECUTE : any unexpected calls on the mock will fail here.
        classUnderTest.DoYourStuff();

        // VERIFY: checks that all expectations have been met
        mock.Verify(); // note: no Assertions.
    }

The important line is:

    mock.Expect("Eat", new IsEqual("cheese"), new IsAnything(), new IsAnything());

This says: expect the Eat() method to be called on the mock, and the three arguments must match the following constraints:

    arg1 == "cheese", arg2 is anything, arg3 is anything.

If Eat() is called with any arguments that don't match these constraints, the test will fail fast.

Constraints

For an expectation to be fulfilled, each parameter passed in by the code under test must match a Constraint.

Constraints are mini rules, such as IsEqual(), IsNotEqual(), IsNull(), IsAnything(), etc. NMock comes with a library of flexible constraints. The main constraints (with examples) are:

 

 

Example

Values that will pass

Values that will fail

 

 

 

 

 

Basic constraints

Most common constraints for testing a value

 

 

 

IsEqual(object expected)

Passes if expected.Equals(actual)

new IsEqual("hello");

"hello"

"boo", "HELLO", "   hello "

IsNull()

Passes if actual is null

new IsNull();

Null

"thing"

IsAnything()

Always passes

new IsAnything();

"foo", 3, new Thingy(), null

(nothing!)

IsTypeOf(Type type);

Passes if actual is of a specific type

new IsTypeOf(typeof(IList));

new ArrayList();

new HashTable();

IsIn(param object[] list)

Passes if actual is equal to any specified value

new IsIn("a", "b", "c");

"a", "b", "c"

"d"

 

 

 

 

 

Chained constraints

Allow contraints to be nested for logic

 

 

 

Not(IConstraint constraint)

Passes only if the constraint fails

new Not(new IsNull());

"hello"

null

Or(IConstraint a, IConstraint b)

Passes if either constraint passes

new Or(new IsEqual("cheese"), new IsEqual("food"))

"cheese", "food"

"parrot"

And(IConstraint a, IConstraint b)

Passes if both constraints pass

 

 

 

NotEqual()

Same as new Not(new IsEqual(…))

 

 

 

NotNull()

Same as new Not(new IsNull())

 

 

 

NotIn(param object[] list)

Same as new Not(new IsIn(…))

 

 

 

 

 

 

 

 

String Constraints

Operate on the ToString() representation of the objects

 

 

 

IsEqualIgnoreCase(object o)

Tests strings, ignoring case

new IsEqualIgnoreCase("hello")

"hello", "HELLO", "hEllO"

"world", 3, "   hello   "

IsEqualIgnoreWhiteSpace(object o)

Tests strings, ignoring whitespace

new IsEqualIgnoreWhiteSpace("hello")

"hello", "  hello ", "h e l\n\rlo"

"HELLO", "foo"

IsMatch(Regex regex)

Tests if actual matches a regular expression

new IsMatch(new Regex("f.*t"))

"fat", "fit", "fart", "foo pat"

"farm"

StartsWith(string prefix)

Tests if actual starts a value

new StartsWith("wa");

"wart", "wa"

"kawa"

 

 

 

 

 

Misc Constraints

 

 

 

 

IsCloseTo(double expected, double tolerance)

Passes if actual is within tolerance of expected

new IsCloseTo(500.0, 0.5)

500.0, 499.6, 500.4

499.0, 501.1

IsListEqual(IList expected)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Special Property Constraint

 

 

 

 

PropertyIs(string propertyName, object expected)

Tests the value of the property of a value instead

 

 

 

 

 

 

 

 

 

Example

 

 

 

 

new PropertyIs("Customer.Address.Street", new IsEqual("Elm Street"))

 

 

 

 

This will pass if actual.Customer.Address.Street == "Elm Street"

 

 

 

The power of constraints is that you can flexibly specify your expectations before your code under test runs, allowing fail fast.

You can easily create custom constraints by implementing the IConstraint interface, or passing a delegate into the Constraint class.

Tips

Syntactic sugar: Because 90% of the time, the two constraints you use are IsEqual() and IsAnything(), these can be replaced with object and null arguments respectively. The above example can be shortened to mock.Expect("Eat", "cheese", null, null).

Test layout: Tests that use mocks are easier to read if they follow a standard layout. We break the test into four parts: "Setup" initializes any objects/mocks and puts them into the correct state before a test. "Expectations" specifies what you expect to happen - this is the actual 'test' bit. "Execute" runs the code under test - this is where you'd typically get a failure. "Verify" performs any post-execution checks including verifying all the mocks expectations have been met and any additional assertions.

Externalize dependencies: Inversion of Control (AKA Dependency Inversion Principle, Dependency Injector Pattern). Passing dependencies in from the outside decouples class under test from a particular implementation of the dependency (a good practice in general), making it easier to mock.

Return values: If the method being mocked returns a value or throws an exception, you can use ExpectAndReturn() or ExpectAndThrow() to specify what the mock should return. You can also use SetupResult() which does not associate an expectation and doesn't care how many times the method is called.

Mocking classes: NMock supports mocking of classes with virtual methods as well as interfaces. The merits of when to mock classes and interfaces is a religious debate. However, use of interfaces is highly recommended.

Don't mock things you don't own: It's awkward and painful trying to mock someone else's API (such as ADO.NET), leading to hard to read tests and assumptions about how the API works. On the other hand, mocking your own APIs leads you down the path of creating cleaner interfaces, which can never hurt. If dealing with external APIs, create your own clean abstraction suited for your purposes, which you can mock easily. For testing the abstraction itself, don't use mocks, use the real thing. This is the opposite of the usage commonly associated with using mocks, which usually leads to brittle and cumbersome tests.

PropertyConstraint: Allows you to setup constraints on properties of objects.