Unit Testing using Unity and the moq frameork

by OSgAgA 24. September 2011 21:45

I strongly believe that unit testing is one of the key technologies for creating reliable and robust applications. In this post I want to introduce you to two frameworks that can help you creating unit tests: Unity and moq.

When creating unit tests you often want to replace a part of your functionality by a simple test routine. For example instead of using a service call to a distant server you just want a simple class that returns the value you need for testing. This can be a chalenging task especially when a complex call hierarchy is involved (see figure 1). Here the unit test calls a method, which calls another method calling a web service. This web service call should be replaced by a call to a simple method always returning the data needed for the given unit test. This can easily be done using the Unity framework.

Lets say we have the following interface with two implementations:

public interface IMyService
{
    string ComplexOperation(string name);
}

public class Service : IMyService
{
    string IMyService.ComplexOperation(string name)
    {
        // Very complex and time consuming code here that is heavily depending on system state.
        return "Return value: " + name;
    }
}

public class ServiceTest : IMyService
{
    string IMyService.ComplexOperation(string name)
    {
        // Simple test functionality
        return "Return Value: Test";
    }
}

Lets assume, that during normal operation of the software the Service implementation is called, but for testing purposes we want to replace the call using the ServiceTest class. With unity we can do this easily by using a unity container as can be seen in the following example:

var container = new UnityContainer();
container.RegisterType<IMyService, Service>();

var myTest = container.Resolve<IMyService>();
Console.WriteLine(myTest.ComplexOperation("OSgAgA"));

container.RegisterType<IMyService, ServiceTest>();

myTest = container.Resolve<IMyService>();
Console.WriteLine(myTest.ComplexOperation("OSgAgA"));

As you can see the class is not created using the new keyword but instead using the Resolve method of the unityContainer. With the RegisterType method you can tell the container, which class should be created for a given interface. With that mechanism you can set the TestService inside your test method and the correct method is called even deep inside a call hierarchy. The only thing is, that the method calling the IMyService interface must know the unity containter. This can easily be done using the dependency mechanisms of the unity framework. If anyone is interested, please write a short comment and I will explain this in a future blog post.

Now that we are able to call test methods, we must be able to produce them in a simple way. This is really important, as in reallity you will often face the problem that you will need many variants of the same interface for different testing scenarios, ending up in hundreds of different implementations of the same interface. Additionaly it sometimes can be a lot of work to create an implementation of an interface espacially if the interface is very complex and you only need to call one method of it.

For creating test methods (stubs or mocks) you can use the moq framework. Here are some simple examples:

var mock = new Mock<IMyService>();

// expected method call will use "OSgAgA" as a parameter.
mock.Setup(hello => hello.ComplexOperation("OSgAgA"))
    .Returns("MyFunnyMock");
Console.WriteLine(mock.Object.ComplexOperation("OSgAgA"));

// expected method call may use any parameter.
mock.Setup(hello => hello.ComplexOperation(It.IsAny<string>()))
    .Returns("MyFunnyMock2");
Console.WriteLine(mock.Object.ComplexOperation("OSgAgA17"));

// expected method call may use any parameter, but the paramter
// is used to create the return value.
mock.Setup(hello => hello.ComplexOperation(It.IsAny<string>()))
   .Returns((string s) => s.ToUpper());

You can see how simple it is to produce simple test methods in a single line of code. The moq framework is pretty easy to learn, as it is heavily based on fluent interfaces (see wikipedia).

In the following code you can see how to combine unity and moq to an effective weapon for unit testing:

mock.Setup(hello => hello.ComplexOperation(It.IsAny<string>()))
  .Returns((string s) => s.ToUpper());
container.RegisterInstance<IMyService>(mock.Object);

var myTest = container.Resolve<IMyService>();
Console.WriteLine(myTest.ComplexOperation("Unity and moq")); 

Here I will end my short introduction to both systems. There is a lot more to be said about them, but that is far beyond the scope of this short blog entry. Please read the corresponding documentation for further information, or leave me a short note if you are interested in some follow up posts.

Tags: , , ,

Add comment




biuquote
  • Comment
  • Preview
Loading


Month List