In my previous post, I explained how to get started with Machine.Specifications (or MSpec for short) and showed you how the syntax for context/specifications looks like when using this BDD framework. For this post, I want to show you how to use an auto mocking container (we’ll be using the one provided by StructureMap off course).
We’ll use the same example as the one used in the previous post, but now we’ll deal with the message handler that makes a particular customer preferred.
The Customer class implements a ‘role interface’ called ICanMakeCustomerPreferred. We retrieve a customer from the repository and make it preferred. We throw an exception in case the customer cannot be found in the data store.
Here are the context/specifications for this easy example:
I want to point out that all fields and properties are made static. This is needed so that the anonymous methods can access them. I’m also using a base class for these specifications which I’ll show next. This base class uses an auto mocking container for providing the requested mocks and stubs through the Dependency and Stub methods.
//
// Subject under test
//
public class MakeCustomerPreferredMessageHandler
{
private readonly ICustomerRepository _repository;
public MakeCustomerPreferredMessageHandler(
ICustomerRepository repository)
{
_repository = repository;
}
public void Handle(MakeCustomerPreferredMessage message)
{
var customer = _repository.Get(message.CustomerId);
if(null == customer)
throw new InvalidOperationException(
"No customer for specified identifier");
customer.MakePreferred();
_repository.Save(customer);
}
}
Notice that I’m using the Establish and Cleanup delegates in the context_specification base class. This doesn’t prevent that these can be used again in derived context/specifications. MSpec ensures that the anonymous methods are called in the right order. This means that the Establish method of the base class is called before the Establish method of the derived context/specifications.
Absolutely no rocket science here, but I figured it might come in handy when you need it. For the next post I’ll try to demonstrate how to deal with reusable behaviors.