Recently a colleague pointed out that my unit test were not following the AAA (Arrange, Act and Assert) structure that they had become accustomed to seeing and as they had understood Unit Tests should be. Although I had argued the point that there were many ways to setup and execute the test I can understand where the confusion can come in when mocking with Rhino Mocks.
I’m an advocate of using what comes natural to you as long as the outcomes are consistent; however I accept that there needs to be some uniformity when working in a team for the simple case of a collective understanding – as long as it is not at the behest of an individual’s ego.
The primary issue boiled down to the difference between the way that the test was prepared in my original blog posting:
[TestMethod]
public void TestInsertValidCustomerContactNameWithSurname()
{
// Create the mock instance
ICustomerRepository customerRepository = m_mockRepository.DynamicMock<ICustomerRepository>();
Customer newEntry = TestHelper.CreateCustomer("James Person");
// Now we set our expectations - when a null is passed the underlying method should throw an exception
Expect.Call(() => customerRepository.Insert(newEntry)).Constraints(Property.Value("ContactName", "James PERSON"));
// Replay our expectations
m_mockRepository.ReplayAll();
// Create a real instance of the CustomerManager that we want to put under test
Managers.CustomerManager manager = new Managers.CustomerManager(customerRepository);
manager.Insert(newEntry);
}
And setting it up in a true AAA sense:
[TestMethod]
public void TestInsertValidCustomerContactNameWithSurname()
{
// Arrange
// Create the stub instance
ICustomerRepository customerRepository = MockRepository.GenerateStub<ICustomerRepository>();
// Create the dummy instance to be used as a parameter
Customer newEntry = TestHelper.CreateCustomer("James Person");
// Create a real instance of the CustomerManager that we want to put under test
Managers.CustomerManager manager = new Managers.CustomerManager(customerRepository);
// Act
manager.Insert(newEntry);
// Assert - here we also check the property value ContactName to make sure that it is as expected.
customerRepository.AssertWasCalled(stub => stub.Insert(newEntry), stub => stub.Constraints(Property.Value("ContactName", "James PERSON")));
}
Notice how the second example shows very distinct Arrange, Act and Assert structure.
Both methodologies result in the same outcome and at the end of the day I would say that you should use what works for you – as long as other people can understand the logic (“What if you should get hit by a bus?”).
