Messages tagged with TDD

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:

[TestMethod]
public void AddressIsEqualToItself()
{
    Address address = new Address("United Kingdom", "Surrey", "Guildford", "St. George Av.", "Elliot House", "GU3 1DA");
 
    Assert.AreEqual(address, address);
}
 
[TestMethod]
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:

[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
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:

MSTest breaking changes in VS2013

Over three years ago I posted a blog showing how you can extend MS Test to verify that code under the test throws expected exception with given message. The solution extends MS Test with new test attribute and reports assertion error when either exception type or message doesn’t satisfy expected values. It is based on the way Microsoft implemented ExpectedExceptionAttribute and works well until you move to Visual Studio 2013.

Unfortunately there are breaking changes in the way VS2013 test runner is working, and as a result the extension doesn’t work any more.