NUnit Mocks

I’ve just been reading up on mocks for testing and they look like a pretty neat and powerful way to improve your testing. I’ve written this sample code based on the example Martin Fowler gives in his excellent article.

This example is of an order which attempts to fullfil itself from a Warehouse. Here’s the Warehouse interface and the Order class which will use it.

[csharp]
public interface IWarehouse
{
bool HasInventory(string Product, int Quantity);
void Remove(string Product, int Quantity);
}

public class Order
{
public int Quantity;
public string Product;
public bool OrderSatisfied = false;

public Order(string Product, int Quantity)
{
this.Product = Product;
this.Quantity = Quantity;
}

public void Fill(IWarehouse warehouse)
{
if (warehouse.HasInventory(this.Product, this.Quantity))
{
warehouse.Remove(this.Product, this.Quantity);
this.OrderSatisfied = true;
}
}
}
[/csharp]

By defining a mock in NUnit 2.2 we can get a mock implementation that will satisfy the requirements of the interface. So our test case is written as

[csharp]
[TestFixture]
public class OrderTest
{
[Test]
public void TestOrderFullfilled()
{
Order order = new Order("widget", 50);
DynamicMock warehouse = new DynamicMock(typeof(IWarehouse));
warehouse.ExpectAndReturn("HasInventory", true, new object[] { "widget", 50 });
warehouse.ExpectAndReturn("Remove", null, new object[] { "widget", 50 });
order.Fill((IWarehouse)warehouse.MockInstance);
Assert.AreEqual(order.OrderSatisfied, true);
warehouse.Verify();
}
}
[/csharp]

1. Create our Order object, passing in the product and quantity at creation time.
2. Then create our Warehouse mock object.
3. Specify the expectations on the mock object. That is, we expect the method “HasInventory” to be called, it will return “true”, and it will expect the parameters “widget” and “50” to be passed in. We also expect the “Remove” method to be called, returning “null” (void return type), and taking the same “widget” and “50” parameters”.
4. Tell our order to fill itself from our mock instance.
5. Verify the order was satisfied
6. Verify the warehouse was satisfied (i.e. all expected methods and parameters were called)

This requires that you write your systems in a decoupled fashion and pass in external dependancies. i.e. if the Order class used a reference to a singleton Warehouse then you wouldn’t be able to test like this.

About these ads

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s