Using the Ninject.MockingKernel is cool…
Ok, so what is so cool about the Ninject.MockingKernel? Here are some of the biggest benefits that I have found so far…
- It saves me from having to worry about test setup code, and I can focus more on arranging the test
- The mocking kernel will manage stub and mock lifetimes for me, so I simply request a stub or mock for the test in question
- It seems like I am less concerned with the state of the “Mocking Framework” (normally Rhino Mocks) because the mocking kernel is managing this for me
So here is a quick sample of how I am using the Ninject.MockingKernel and more specifically the RhinoMocksMockingKernel…
Here is the test setup…
[SetUp]
public void Setup()
{
container = new RhinoMocksMockingKernel();
controller = container.Get<UsersController>();
customerRepository = container.Get<ICustomerRepository>();
}
Notice in the setup that I didnt need to execute any calls to MockRepository.GenerateStub<T>() or MockRepository.GenerateMock<T>(). Also notice that I use the auto mocking container to create an instance of my controller. In my setup I can initalize a member level variable and use this variable in each test OR in each test I can call Get<T>() on the container. Either way, the stubs and mocks that are returned from the auto mocking container can be used as stubs or mocks and I can make assertions on those mocks and stubs.
Here are the two tests that exercise the “Delete” method of my “UsersController”…
[TestCase(123, 456, "joe")]
[TestCase(456, 789, "jim")]
public void Delete_Updates_CustomerStatistics(int customerId, int userId, string userName)
{
var testCustomer = new Customer { Id = customerId };
container.Get<ICustomerRepository>().Stub(it => it.FindCustomerForUser(userId)).Return(testCustomer);
container.Get<ICustomerRepository>().Expect(it => it.UpdateCustomerStatistics(customerId)).Return(1);
controller.Delete(userId, userName);
container.Get<ICustomerRepository>().VerifyAllExpectations();
}
[TestCase(123)]
[TestCase(456)]
public void Delete_Loads_RelatedCustomer(int userId)
{
var testCustomer = new Customer { Id = 123 };
container.Get<ICustomerRepository>().Expect(it => it.FindCustomerForUser(userId)).Return(testCustomer);
controller.Delete(userId, "joe");
container.Get<ICustomerRepository>().VerifyAllExpectations();
}
And here is the code under test…
[HttpPost]
public ActionResult Delete(int userId, string userName)
{
var customer = customerRepository.FindCustomerForUser(userId);
userRepository.DeleteUser(userId, userName);
customerRepository.UpdateCustomerStatistics(customer.Id);
return new JsonResult
{
Data = new Ack
{
Status = AckStatus.Success,
Message = "User deleted"
}
};
}
Another interesting note, is that the code under test actually has a dependency on the “userRepository” and you should have noticed that nowhere in my test or my test setup did I create a mock or stub for IUserRepository.
Here is the constructor for my UsersController:
public UsersController(IUsersRepository userRepository, IMembershipService membershipService, IRolesService rolesService, ICustomerRepository customerRepository)
{
this.rolesService = rolesService;
this.membershipService = membershipService;
this.userRepository = userRepository;
this.customerRepository = customerRepository;
}
So, if you are looking for some new tools to add to your testing tool belt, consider taking the Ninject.MockingKernel for a test drive…
If you are using VS.NET 2010 you can download the package via NuGet or you can get the code from here.