Archive for the ‘Unit Tests’ Category

Dependeny Injection vs Encapsulation

November 24, 2008

Dependency Injection vs Encapsulation

When trying to show coworkers of the advantages of Dependency Injection I often encounter the argument, that it hurts one of the major object-oriented principles – encapsulation.

Let us consider the following basic example of class that has two dependencies, created in the constructor:

public class SomeClass
{
	IWriter writer;
	ILogger logger;

	public SomeClass()
	{
		this.writer = new StreamWriter();
		this.logger = new RegistryLogger();
	}
}

Client code:

SomeClass someClass = new SomeClass();

SomeClass has direct dependencies and can’t be used without them and is clearly not testable. Let us see a implementation with dependency injection:


public class SomeClass : ISomeClass
{
	IWriter writer;
	ILogger logger;

	public SomeClass(IWriter writer, ILogger logger)
	{
		this.writer = writer;
		this.logger = logger;
	}
}

This is clearly much better, but is considered to be violating the encapsulation principle form some developers. Encapsulation principle tells us to hide the class inner workings form the user. This is important in order to allow us to change the class implementation without changing all of its clients. This is a valid point, that I respect, we all strive to the “low maintenance road” (Ayende) – the most important thing in software development.

However let us look at the client code and see if it actually breaks the encapsulation principle:

ISomeClass someClass = Container.Resolve<ISomeClass>();

What we see here is that, the client code does not even know a damn thing about the class dependencies!
We just let the dependency injection container do the heavy lifting for us and don’t worry how to create all of the class dependencies.
In practice we actually do not even have the possibility to use the constructor!
That’s true – in production code instantiating a class from the constructor would require creating all of its dependencies, which would require instantiating their dependencies and so on. It would be safe to say, that the developers can’t even use the constructor and must instantiate their objects using the dependency injection container, which is so much easier.

So the user of the code does not actually even know what kind if dependencies a class has – all of this because of the dependency injection container. So actually instead of breaking encapsulation we are driving it to a whole new level – each individual class does not get to decide what kind of object it needs – everything gets configured in the configuration of the container. This definitely does not break the encapsulation principle. It makes it hold even stronger.

As a side note I want to point out, that I am definitely against the point of view “If you let the developers to bad things, then they will”. If you don’t trust your developers you shouldn’t hire them in the first place. Treat all the of the developers as stars and they will be.

Happy dependent less programming!

Unit Tests 101 – how to write testable code

November 22, 2008

Reposting this entry I wrote for my company’s blog

Hi, I am Test Engineer at AutoScout24 in Munich and will be writing about Unit Tests, testability, Acceptance Tests and developing high quality software. In this post I want to go in go into the testability topic – what makes code testable and what not. It may seem obvious how to do it for the people, that are going the TDD way, but sometimes it is hard for new developers to adopt the art of writing Unit Tests.
Writing Unit Tests is all about being able to use the classes you develop in isolation, without having to instantiate their external dependencies, or a database, filesystem, webserver or something else running.
So it all boils down to the question – how to make the class dependencies exchangeable. Let’s assume we have the following code:

Code:

public class ClassInTest {
 public bool DoStuff() {
   IExternalDependency dependency = new ExternalDependency(...);
   return dependency.Something();
 }
}

Unit Test:
impossible to write

For this example we have pretty simple code to test and just want to concentrate in making it testable.
The main issue with this code is that, the class instantiates the ExternalDependency by itself. Considering that when writing an Unit Test we are interested in the functionality of ClassInTest only, we would like to ignore the ExternalDependency and replace it with some kind of fake implementation

The first approach would be to encapsulate the object instantiation with a static method within the class.

Code:

public class ClassInTest {

  static IExternalDependency dependency;

  public static IExternalDependency CreateExternalDependency(...) {
    if(dependency == null) {
      dependency = new ExternalDependency(...);
    }
    return dependency;
  }

   public static void SetExternalDependency(IExternalDependency aDependency) {
     dependency  = aDependency;
   }

   public bool DoStuff() {
     IExternalDependency dependency = CreateExternalDependency(...);
     return     dependency.Something();
   }
}

Unit Test:
public class ClassInTestTest {
  public void DoStuffTest() {
    IExternalDependency mock = new Mock<IExternalDependency>();
    mock.Expect(x => x.Something()).Returns(true);
    ClassInTest.SetExternalDependency(mock.Object);

    ClassInTest classInTest = new ClassInTest();
    Assert.IsTrue(classInTest.DoStuff());
  }
}

To go one step further we could write a class responsible only for object creation – a factory.

Code:

public class ClassInTest {

  public bool DoStuff() {
    IExternalDependency dependency = CreateExternalDependency(...);
    return     dependency.Something();
  }
}

public class ClassInTestFactory {
  static IExternalDependency dependency;

  public static IExternalDependency CreateExternalDependency(...) {
    if(dependency == null) {
      dependency = new ExternalDependency(...);
    }
    return dependency;
  }
}

  public static void SetExternalDependency(IExternalDependency aDependency) {
    dependency  = aDependency;
  }
}

Unit Test:
public class ClassInTestTest {
  public void DoStuffTest() {
    IExternalDependency mock = new Mock<IExternalDependency>();
    mock.Expect(x => x.Something()).Returns(true);
    ClassInTestFactory.SetExternalDependency(mock.Object);

    ClassInTest classInTest = new ClassInTest();
    Assert.IsTrue(classInTest.DoStuff());
   }
}

This way we have clean separation between classes, that know how to create objects and classes who do the actual work. As a side effect we have to write a factory class for every second class in the application.

The last and clearly the best approach we are going to examine is the dependeny injection path – let all the wiring work to an external container, which knows how to create all registered classes and do not bother writing code for this yourself, be it a static method within the class or factory. The point is to have each class to declare its dependencies in the constructor or as properties

Code:

public class ClassInTest {
  public ClassInTest(IExternalDependency dependency) {
    this.dependency = dependency;
  }

  public bool DoStuff() {
    return     dependency.Something();
  }
}

Unit Test:
public class ClassInTestTest {
  public void DoStuffTest() {
    IExternalDependency mock = new Mock<IExternalDependency>();
    mock.Expect(x => x.Something()).Returns(true);

    ClassInTest classInTest = new ClassInTest(mock.Object);
    Assert.IsTrue(classInTest.DoStuff());
  }
}

This is clearly less code and makes it easier to test, the important thing is to examine the client code – how is ClassInTest used in production, without the container:

Client Code without usage of dependency injection container:

ClassInTest classInTest = new ClassInTest(new ExternalDependency());

In real life when you have a lot of dependencies, each of them having a lot of other dependencies it is very hard burden to pass all the arguments by yourself. Let the container do it for you.

Client with dependancy injection:

ClassInTest classInTest = container.Resolve<ClassInTest>();

Notice that you don’t have to bother what does the ClassInTest need to be instantiated. The “magic” is that IExternalDependency is registered within the container, so we just request some object and let the container do the heavy lifting – examining what constructors it has and resolving the needed arguments.

If are you looking for dependency injection container you can try AutoFac, Castle Windsor, StructureMap or Microsoft Unity, just to name a few.

It is not always possible to switch to dependency injection in a large project – then factories are you best choice. But keep in mind, that dependency injection is the way to go and do your best to prepare your project for it.

Happy programming!