Messages tagged with Patterns

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.

Using policies to handle exceptions while calling external services

Exception handling very easily gets ugly. Typical try...catch block clutters method and grows with any new exception discovered. Then, bits of code are copied between methods which require same error handling. Adding any new logic into error handling is a nightmare and with each new release it seems like the same errors are coming back.

Policies for handling exceptions

To overcome those problems we can extract logic related to exception handling into separate objects – policies. This will keep main business logic clear, allow reusing and make testing easy.

Here’s the definition for recoverable policy:

public interface IRecoverablePolicy<TResult>
{
   TResult Execute(Func<TResult> operation);
}

One example of recoverable policy is handling transient exceptions. Usually they require retrying method call after a small pause.

Single Responsibility Principle applied to exception logging

In the previous post How to log exceptions I said that you should let your logging framework handle exception logging. In this post I will explain why it is a bad idea to generate log messages in the catch block.

Lets first look at an example:

try
{
    UpdateAccount(userAccount);
}
catch (SqlException e)
{
    var sb = new StringBuilder();
    sb.AppendLine(e.ToString());
    sb.AppendFormat("Sql number: {0}", e.Number);
    sb.AppendFormat("Sql procedure: {0}", e.Procedure);
    sb.AppendFormat("Sql server: {0}", e.Server);
 
    logger.Error(sb.ToString());
}