Click here to Skip to main content
Click here to Skip to main content

Unit Testing with Unity Application Block

, 12 Feb 2011
Rate this:
Please Sign up or sign in to vote.
Using Unity Application block to perform unit testing

Introduction

This article would discuss how to use Unity Application Block for unit testing. Unity Application Block provides a dependency injection container. It is available as part of Microsoft Enterprise Library and separately as well. It can be downloaded from here.

Background

Unit testing most commonly needs a test program and mock objects / stubs. Test program would be the test projects provided by Visual Studio. Now, one does not need to write code for creating Unit under test and initialize it with respective mock or stubs to be able to do testing in isolation. This can be accomplished through Unity and one can just concentrate on writing better tests for the unit under test.

Unit Testing

Automating unit testing allows developers and testers a better and quick way to test their code for logical errors. Once created, running these tests as the code changes and adding more tests makes sure that the developer working on it has not introduced any defects.

Following are some of these guidelines to keep in mind while writing unit tests:

  • Single Condition Tests.
  • Test concerns separately, for example, there should be separate tests for Business and Data access layers.
  • Minimize test overlap.
  • Defect Localization, keeping unit tests small, in case of a defect, it will be easy to locate it based on the failing test.
  • Keep Tests Independent, Fresh Fixture strategy would help.
  • Self checking Tests, using Built-in/Custom Assertions.
  • Purpose of the test should be very clear.
  • Minimize un-testable code.
  • Keep test logic out of production.
  • Tests should be repeatable.
  • Write the unit test first. This is optional depending on if test-driven development or test-first development is used.

Also, some of the guidelines and patterns for organizing unit test such as Testcase class per Feature, Testcase class per Fixture can be considered.

Unity Application Block

Unity Application Block provides a dependency injection container. Dependency Injection is a pattern allowing loose coupling on the principle of separating behavior from dependency resolution. Unity is a lightweight and extensible dependency injection container that supports injection through constructor, property and method call. It can help in de-coupling, simplifying design and testing of the application.

Design

Design1.JPG

Layered architecture simplifies automated testing, as simple as 3-Tier architecture would do. In the above diagram, I have shown ICustomerFacade, ICustomerManager implemented by CustomerFacade, CustomerManager components respectively. This is Interface-based programming; interfaces provide contract or specification for implementation, all the classes implementation should conform to the contract. We need to have interface at each component. In terms of dependency injection, a dependent consumer.

Using the Code

Before we start on the steps for creating and configuring unity, it’s required to have Enterprise Library 5.0 or Microsoft Unity 2.0 installed.

To begin with, we take an example of the business facade class CustomerFacade, this is how it looks:

public class CustomerFacade : ICustomerFacade
{
    [Dependency]
    public ICustomerManager CustomerManager { get; set; }

    #region ICustomerFacade Members

    public long CreateCustomer(Customer customer)
    {
        try
        {
            return CustomerManager.CreateCustomer(customer);
        }
        catch (Exception e)
        {
            throw new BusinessException("BusinessException Occurred", e);
        }
    }

    #endregion
}   

For the sake of simplicity, I have taken a vanilla example.

The properties to be resolved using unity should be marked with DependencyAttribute. In the above code, CustomerManager property has this attribute.

CustomerFacade implements interface ICustomerFacade, there by separating behavior from dependency:

public interface ICustomerFacade
{
    long CreateCustomer(Customer customer);
}

Now, we will see how we can test CustomerFacade with the help of Unity Application block:

Step 1: Create Test project and add references

  1. Add a test project to the solution in Visual Studio.
  2. Add references to Microsoft.Practices.Unity, Microsoft.Practices.Unity.Configuration, System.Configuration.

Step 2: Add Test class

  1. Add a test class to the test project created in Step 1.
  2. Import namespaces .Practices.Unity, Microsoft.Practices.Unity.Configuration, System.Configuration.

Step 1 and Step 2 can be automated using Visual Studio 2008 Professional

  1. Right click on the method and choose Create Unit Tests…
  2. In the dialog box, select the methods to be included for automatic Test class and method generation.
  3. Select an Existing or New Test project
  4. Click Ok

Step 3: Add an App.config file to the test project created in Step 1.

Step 4: Setup the Unity Configuration part of the App.config file created in Step 3:

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

  <configSections>
      <section name="unity" 
	type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, 
	Microsoft.Practices.Unity.Configuration"/>
  </configSections>

<unity xmlns="http://schemas.microsoft.com/practices/2010/unity"
<assembly name="UnitTestingWithUnity" />
<assembly name="UnitTestingWithUnity.Test" />
<namespace name="UnitTestingWithUnity.BusinessFacade" />
<namespace name="UnitTestingWithUnity.Business" />
<namespace name="UnitTestingWithUnity.Data" />
<namespace name="UnitTestingWithUnity.Test.Mock" />

<container>
<register type="ICustomerManager" mapTo="MockCustomerManager" />
<register type="ICustomerDataAccess" mapTo="MockCustomerDataAccess" />
</container>

</unity>
</configuration>       

Understanding the configuration file:

  1. Add the UnityConfigurationSection reference to your configuration file.
  2. Add all the assembly and namespaces required to resolve the interface and the implementation classes in the configuration.
  3. MockCustomerManager class implements interface ICustomerManager.
  4. Register the interfaces to be resolved using the container with the respective map to class.

Step 5: Writing your test:

TestInitilize method should initialize the unity container to load the unity configuration created in the previous step.

private IunityContainer unityContainer;

[TestInitialize()]
public void MyTestInitialize()
{
    unityContainer = new UnityContainer();
    unityContainer.LoadConfiguration();
}

Unity container can be initialized without using the configuration files as well. Instead of LoadConfiguration, we should use RegisterType method on unity container.

unityContainer.RegisterType<ICustomerManager, CustomerManager >();
unityContainer.RegisterType<ICustomerDataAccess, CustomerDataAccess>();

In the test method, we will use the unity container we just created to resolve the CustomerFacade class.

/// <summary>
///A test for CreateCustomer
///</summary>
[TestMethod()]
public void CreateCustomerTest2()
{
ICustomerFacade target = new CustomerFacade();
target = unityContainer.BuildUp<ICustomerFacade>(target);
Customer customer = new Customer{Name="Test 1", Address = "Test Address 1" };
long custId = target.CreateCustomer(customer);Assert.AreEqual(custId, 1);
}

For Unity to resolve all the dependencies, we should use the dependency injection container provided by Unity to construct and initialize objects. It can be done in 2 ways:

Create the object with new operator, and then use BuildUp method on unity container to resolve all the dependencies:

ICustomerFacade target = new CustomerFacade();
target = unityContainer.BuildUp<ICustomerFacade>(target); 

Alternatively, use Resolve generic method to create and resolve dependencies in one go:

ICustomerFacade target = unityContainer.Resolve<CustomerFacade>(); 

Step 6: Execute the Test just created.

That’s about it.

References

History

  • 12th February, 2011: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Vivek Krishnamurthy
Architect
India India
No Biography provided

Comments and Discussions

 
GeneralMy vote is excellent - but still some some comments PinmemberGeorge Mamaladze22-Jun-11 8:16 
Thank you Vivek for demonstrating us how to build testable classes and DI testing techniques using Unity framework. Nevertheless I agree with Mike's comments partially.
 
"Keep Tests Independent" - sharing container, which can also be configured to deliver singletons, across test might cause test interdependancy.
 
"Test concerns separately" - if you share container between tests having different concerns you are configuring it to contain dependencies for both of them. So the container might contain "too much" staff and if your code under test uses "unallowed staff", you will never detect it.
 
Using XML file for container configuration does not give you flexibility to use different mocks for same interface in different tests. Let's say you are testing a logger. In one test you want it to log a message, in another you want it to throw an exception. Are you going to write a universal mock for both cases? What about DI?
 
My suggestion is to use one contaier per test.
Do not use XML at all. Fill the container every time for each test individually.
 
------------------------------------------------------
 
Unity is not a testing or mocking framework.
It makes no sense using Unity just for testing puposes.
It is agreat idea to use Unity in Applications where it makes sense.
When testing such applications you should inject dependencies the same way you do it in productive code, does not metter wether you use some other mocking / testing framework or not.
GeneralRe: My vote is excellent - but still some some comments PinmemberVivek Krishnamurthy22-Jun-11 21:02 
GeneralRe: My vote is excellent - but still some some comments Pinmemberkashink1-Jan-14 5:27 
GeneralMy vote of 1 Pinmembermr_lasseter13-Feb-11 12:01 
GeneralRe: My vote of 1 PinmemberVivek Krishnamurthy15-Feb-11 1:34 
Generaldon't think your unit test should be dependent on the container Pinmembermr_lasseter12-Feb-11 12:14 
GeneralRe: don't think your unit test should be dependent on the container PinmemberVivek Krishnamurthy13-Feb-11 19:59 
GeneralRe: don't think your unit test should be dependent on the container Pinmembermr_lasseter14-Feb-11 3:00 
GeneralRe: don't think your unit test should be dependent on the container PinmemberVivek Krishnamurthy14-Feb-11 5:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140718.1 | Last Updated 12 Feb 2011
Article Copyright 2011 by Vivek Krishnamurthy
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid