Messages tagged with UnitTesting

Create test objects using Factory Methods or Object Mother pattern

One of the nightmares in unit testing is creating instances of tested objects. While our tested object grows, very quickly the code repetition appears in the test fixture. It is very important to keep unit test code clean, so the changes to tested object can be easily introduced. It’s also important for unit test code to be easy to read. Very often you can find following code in the test fixture:

public void AddressIsEqualToItself()
    Address address = new Address("United Kingdom", "Surrey", "Guildford", "St. George Av.", "Elliot House", "GU3 1DA");
    Assert.AreEqual(address, address);
public void AddressesAreEqualWhenAllFieldsAreEqual()
    Address address = new Address("United Kingdom", "Surrey", "Guildford", "St. George Av.", "Elliot House", "GU3 1DA");
    Assert.AreEqual(new Address("United Kingdom", "Surrey", "Guildford", "St. George Av.", "Elliot House", "GU3 1DA"), address);
    Assert.AreNotEqual(new Address("United States", "Surrey", "Guildford", "St. George Av.", "Elliot House", "GU3 1DA"), address);
    Assert.AreNotEqual(new Address("United Kingdom", "Middlesex", "Guildford", "St. George Av.", "Elliot House", "GU3 1DA"), address);
// more tests requiring instances of Address

Create test objects using Builder pattern and methods chaining

In my previous post “Create test objects using Factory Methods or Object Mother pattern” I described how Factory Method and Object Mother patterns can be used to help with creating object instances. Presented solution allows to remove code duplication from unit tests making them easier to adopt changes in tested objects, but doesn’t help much with test code readability, which is very important factor in maintaining unit tests. Using sample Address class from the previous article, imagine following code:

Address address = new Address("Poland", "Slask", "Zabrze", "Chrobry", "13", "46-230");

For someone who doesn’t know a lot about Poland’s geography and addressing system, it is really hard to recognise which parameter represents County, City or Street, and when it comes to numbers the situation is even worse. To solve the mystery meaning of parameters, reader must go to class definition or use help from tools such as IntelliSense. Maybe it doesn’t seem like much effort, but it breaks the reading process and de-concentrates reader. It is like reading a book in foreign language with many new words. The reader spends more time going through the dictionary than reading a book and in effect doesn’t remember much from what she read. Soon, the reader stops checking every unknown word in the dictionary and starts to assume its meaning from the context, although in many cases the assumption is wrong (Some of the novels I read when I was learning English I read several times, and every time it was like reading different book). To help the reader with understanding the unit test, it must be written in a way that there is no need to leave the page or assume any meaning, but code is kept conscience and free from duplication.

MSTest: ExpectedExceptionWithMessageAttribute

The unit testing system which comes with Visual Studio offers a way to assert whether a test has thrown specific exception. It is done by using ExpectedExceptionAttribute on test method:

public void ThrowsInvalidOperationException()
    throw new InvalidOperationException();

The problem with this solution is that it checks only for the type of the exception, but there is no way to assert exception’s message (There is overloaded constructor which takes string as a second parameter, but this string is not a message to assert, but it is a message which will be displayed when assertion fails.). As exceptions are an important part of application’s domain, our unit tests should assert them and check whether messages are containing useful and valid information. Below example, which is very simplistic, shows how one exception type may reference to two different conditions:

Arranging mocks using DSL

One of the biggest problems with unit tests is poor readability. Bad naming convention, long methods, hard to understand Arrangement and Assert parts are making unit tests one of the hardest code to read and refactor. In previous article, Unit Tests as code specification, I presented the way to increase readability of test method names and use them to create code specification. Now I would like to tackle the problem of unreadable test methods.

Most of unit tests methods start with test arrangement. It usually takes a form of setting up mocks and initialising local variables. It’s not uncommon to start the test with code similar to the one below:

_testService.Expect(i => i.Foo()).Throw(new WebException("The operation has timed out")).Repeat.Once();
_testService.Expect(i => i.Foo()).Return(9).Repeat.Once();

Unit Tests as code specification

When asking people what is the purpose of writing unit tests we usually get following answer:

“To verify that the code actually does what it is supposed to do.”

Among other responses we will find that unit tests help to validate that changes are not breaking existing functionality (regression), or that practising TDD will guide the design. But are those the only purposes? Well, there is more. Because unit tests are executing our code, they can show how it is working. We can use them as a specification of the code. Well crafted tests, which have explaining names and are easy to read, create a live specification of the module, which is always up to date.

Whenever we need to analyse a class, whether because we are new to it or we are coming back, we can use reports from unit tests to get the understanding how the class is working and what is it’s contract.

To build a specification from unit tests, we need to keep them organised and apply proper naming convention.