About

When writing unit tests for any code that uses dependency injection, and when using a mocking framework, we need to declare and inject any dependency we have. This is repetitive and boring code to write, especially on classes with many dependencies. AutoMock solves this by creating mocks/stubs on the fly for a given class together with an instance of it.

Features

  • Creates mocks/stubs on the fly for any class under test that depends on a set of dependencies through constructor based dependency injection.
  • Currently supports RhinoMocks.

Getting started

  1. Download the latest version of AutoMock via nuget.org.
  2. In your code, import the namespace AutoMock.
  3. Have a look at the sample code below for more information.

Sample code

The class to test:

The class below uses constructor based dependency injection. It updates the data source with the customer name, writes a new event to the log and sends a notification e-mail.

public class CustomerUpdater
{
	private ICustomerDataProvider _customerData;
	private IMailSender _mailSender;
	private ILogWriter _logWriter;

	public CustomerUpdater(
		ICustomerDataProvider customerData,
		IMailSender mailSender,
		ILogWriter logWriter)
	{
		_customerData = customerData;
		_mailSender = mailSender;
		_logWriter = logWriter;
	}

	public void UpdateCustomerName(int customerId, string name, string email)
	{
		var customer = _customerData.GetCustomer(1);

		customer.Name = name;

		_customerData.UpdateCustomer(customer);

		_logWriter.Write(string.Format("Customer {0} has been updated", name));

		_mailSender.SendMail(email, string.Format("Customer {0} has been updated", name));
	}
}


Unit test without using AutoMock:

[TestMethod]
public void UpdateCustomerName_email_should_be_sent_when_customer_name_is_updated()
{
	var customerData = MockRepository.GenerateStub<ICustomerDataProvider>();
	customerData.Expect(x => x.GetCustomer(0)).IgnoreArguments().Return(new CustomerItem());
	var mailSender = MockRepository.GenerateStub<IMailSender>();
	var logWriter = MockRepository.GenerateStub<ILogWriter>();

	var customerUpdater = new CustomerUpdater(customerData, mailSender, logWriter);

	customerUpdater.UpdateCustomerName(1, "Frank", "frank@somecompany.com");

	mailSender.AssertWasCalled(x => x.SendMail(null, null), x => x.IgnoreArguments());
}

Unit test using AutoMock:

[TestMethod]
public void UpdateCustomerName_email_should_be_sent_when_customer_name_is_updated()
{
	var autoMocker = new RhinoAutoMocker<CustomerUpdater>();
	autoMocker.Get<ICustomerDataProvider>().Expect(x => x.GetCustomer(0)).IgnoreArguments().Return(new CustomerItem());

	autoMocker.ClassUnderTest.UpdateCustomerName(1, "Frank", "frank@somecompany.com");

	autoMocker.Get<IMailSender>().AssertWasCalled(x => x.SendMail(null, null), x => x.IgnoreArguments());
}

By using AutoMock we save some lines of code for every test we write, the test also gets smaller in size, thus easier to read and understand.

Last edited May 18, 2016 at 9:51 AM by define, version 7