Posts tagged ‘Dependency Injection’

Wow – June 24th was the last entry! First of all I need to apologize for my bad blogging; I have no other excuse except for the volume of work AT work. Sure I could have re-prioritized and it may have made a difference, but I don’t think my employer would have been very pleased.

So, New England Code Camp, Microsoft Offices, Waltham, MA – full information can be found at http://www.thedevcommunity.org/Events/PresentationList.aspx?id=13. Today I am giving two presentations:

Using Entity Framework’s New POCO Features: Part 2 (Unit Testing)

Level: Intermediate

Starts: Oct 17 2009 2:50 PM

Ends: Sep 17 2009 4:05 PM

Room: MPR A

Speaker: James Phillips

In many cases Unit Testing is considered a chore rather than another development task and often ends up being the last task in a development cycle. More often than not, the sheer work involved in preparing unit tests for existing code can lead to the production of Integration Tests rather than true Unit Tests. Where a unit of code that is under test relies on an external resource, such as a Database or Configuration file, the dependency can lead to testing of the underlying mechanism as well as the unit being tested. This was especially true with Entity Framework 1.0 shipped with .NET Framework 3.5 Service Pack 1. With the advent of .NET Framework 4.0, the Entity Framework has advanced in favor of better Unit Testing with the use of POCO and the ability to create interfaces based on IObjectSet. This presentation will cover the examples that can lead to true Unit Testing as opposed to Integration Testing and provide valuable feedback metrics such as code coverage and automated build time reporting of results.

SCRUM and TFS

Level: Introductory

Starts: Oct 17 2009 4:10 PM

Ends: Sep 17 2009 5:25 PM

Room: Rhode Island

Speaker: James Phillips

SCRUM has grown in popularity and acceptance by many companies over the world with numbers of registered SCRUM Masters reaching 51,955 (11 March 2009 – Jeff Sutherland). Although SCRUM does not stipulate what tools to use to produce the necessary artifacts, Microsoft Team Foundation System provides a number of features via TFS Explorer that facilitate capturing the artifacts of SCRUM and is a useful tool for any SCRUM Master, Team and Product Owner. This presentation will highlight the SCRUM framework and show you practical use of TFS and other tools that facilitate the ceremonies and artifacts of SCRUM.

The slides and code are available for download here:

SCRUM_And_TFS.zip

EF_POCO_And_UnitTesting_slides.zip”

EF_POCO_And_UnitTesting_code.zip

EF_POCO_And_UnitTesting.zip

  • Share/Bookmark

Finally! I’ve been itching to get into the latest incarnation of the EF for a while now and finally I had the opportunity to take it around the block (kick the tires and generally rough it up). My main interest in EF 2.0 was the supposed support for Unit Testing and the improvements on using POCO to map to the Data Model.

I have to admit, although I liked EF 1.0 when I first started using it, one of my biggest bug bears was the fact that you had to “disconnect” your entities before you could really work with them outside the context (no pun intended) of the Entity Framework. I was also quite miffed when I discovered there was no easy way to mock the underlying data layer so I ended up with code like this:


    /// <summary>
    /// Loads a customer instance with the relevant information from the database.
    /// </summary>
    /// <param name="i_customerId">The customerId of the customer data to be retrieved.</param>
    /// <param name="o_customer">The customer instance to be created.</param>
    public void Load(string i_customerId, out Customer o_customer)
    {
        if (string.IsNullOrEmpty(i_customerId))
        {
            throw new ArgumentException("Parameter cannot be null.", "i_customerId");
        }
        int numericVal;
        if (!int.TryParse(i_customerId, out numericVal))
        {
            throw new ArgumentException("Parameter cannot be non-numeric.", "i_customerId");
        }
        if (numericVal < 0 || numericVal > 9999)
        {
            throw new ArgumentOutOfRangeException("i_customerId");
        }

        m_customerRepository.Load(i_customerId, out o_customer);

        if (o_customer != null)
        {
            if (!string.IsNullOrEmpty(o_customer.ContactName) && o_customer.ContactName.Contains(" "))
            {
                o_customer.ContactName = o_customer.ContactName.Trim(' ');
                string[] names = o_customer.ContactName.Split(' ');
                if (names.Length > 1)
                {
                    names[names.Length - 1] = names[names.Length - 1].ToUpper();
                }
                o_customer.ContactName = string.Join(" ", names);
            }
        }
    }

In this case, m_customerRepository is the injected ICustomerRepository instance. When we look at the implementation of the actual data layer class (which does not get tested by the Unit Test, we find that inside the Load method we have the following:


    /// <summary>
    /// Loads a customer instance with the relevant information from the database.
    /// </summary>
    /// <param name="i_customerId">The customerId of the customer data to be retrieved.</param>
    /// <param name="o_customer">The customer instance to be created.</param>
    public void Load(string i_customerId, out BaseCustomer o_customer)
    {
        Customer customer = (CustomerSet.Where(cust => !string.IsNullOrEmpty(cust.CustomerID) &&
                                                       cust.CustomerID == i_customerId)).First();
        if (customer != null)
        {
            o_customer = new BaseCustomer()
                             {
                                 Address = customer.Address,
                                 City = customer.City,
                                 CompanyName = customer.CompanyName,
                                 ContactName = customer.ContactName,
                                 ContactTitle = customer.ContactTitle,
                                 Country = customer.Country,
                                 CustomerID = customer.CustomerID,
                                 Fax = customer.Fax,
                                 Phone = customer.Phone,
                                 PostalCode = customer.PostalCode,
                                 Region = customer.Region
                             };
        }
        else
        {
            o_customer = null;
        }
    }

Not the best way of doing things, that is for sure! In fact it is downright ugly (IMHO). So when I heard that there were improvements to the EF for .NET 4.0, especially in the area of Unit Testing I was curious to say the least. As I delved in deeper I started finding more and more things that made it more attractive to my style of development. For example one of the beauties of EF 2.0 is the fact that you can remove the CustomTool that generates the entity classes that are bound to the data model (through the edmx file). When you do this, you effectively get rid of the code generation for the EF instance that you have loaded in your project. There are some excellent examples (and walkthroughs available) from the ADO.NET Team blog:

POCO in Entity Framework : Part 1 – The Experience (excellent walkthrough on removing the CustomTool)

POCO in Entity Framework : Part 2 – Complex Types, Deferred Loading and Explicit Loading

POCO in Entity Framework : Part 3 – Change Tracking with POCO

So now what? Great! So now I can use my POCO to update the Data Model. But I still hadn’t found out how to do true unit testing with DI and mocking? I was quite flummoxed until I realized (with a helpful pointer from a friend at Microsoft – thanks Jason) that the answer was staring me in the face:

“Can’t you create a mock class that derives from IObjectSet instance yourself, or is there a problem doing that?”

Well yes, I did have a problem with that – it meant that I would have to write more code. I was naively hoping to have something like:


List<Customer> cusList = TestHelper.CreateCustomerList();
IObjectSet<Customer> context = cusList.AsObjectSet();

So I was being lazy… I guess that, with each version of .NET, I had become more and more accustomed to so much being done for me that stumbling across something as “simple” as creating an AsObjectSet() function that was not available was bit of a shock. More so when you look at what IS available on a List<entity> method / property list.

At first I contented myself with just doing what was obvious – create a mock class that inherited from IObjectSet<Customer>, before I realized (with another push from Jason) that I could make it more generic and have a MockObjectSet<T> class:


    internal class MockObjectSet<T> : IObjectSet<T>
        where T : class
    {
        public MockObjectSet(List<T> entityList)
        {
            if (entityList == null)
            {
                throw new ArgumentNullException("entityList");
            }
            else
            {
                _repository = entityList.ToList();
            }
        }

        IList<T> _repository;

        #region IObjectSet<T> Members

        public void AddObject(T entity)
        {
            _repository.Add(entity);
        }

        public void Attach(T entity)
        {
            this.AddObject(entity);
        }

        public void DeleteObject(T entity)
        {
            _repository.Remove(entity);
        }

        #endregion

        #region IEnumerable<T> Members

        public IEnumerator<T> GetEnumerator()
        {
            return _repository.GetEnumerator();
        }

        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return _repository.GetEnumerator();
        }

        #endregion

        #region IQueryable Members

        public Type ElementType
        {
            get { return typeof(T); }
        }

        public System.Linq.Expressions.Expression Expression
        {
            get { return _repository.AsQueryable<T>().Expression; }
        }

        public IQueryProvider Provider
        {
            get { return _repository.AsQueryable<T>().Provider; }
        }

        #endregion
    }

It is important to note here that the TestHelper.CreateCustomerList() function has several overrides and returns a List<Customer> filled with dummy data.

After playing around a bit I realized that I could actually just create an Extension Method that would create an instance of the mock CustomerSet and therefore I could call it from within my Unit Test code. The Extension Method looks like this:


    public static class ObjectSetExtension
    {
        public static IObjectSet<T> AsObjectSet<T>(this List<T> entities) where T : class
        {
            return new MockObjectSet<T>(entities);
        }
    }

Now if we revisit the unit test code, we get the following:


        [TestMethod]
        public void TestLoadValidCustomerContactNameWithSurname()
        {
            // Arrange
            // Create the stub instance
            INorthwindContext context = MockRepository.GenerateStub<INorthwindContext>();
            // Create the dummy data
            const string customerId = "555";
            const string contactName = "James Person";
            IObjectSet<Customer> customers = TestHelper.CreateCustomerList(contactName, customerId).AsObjectSet();

            // declare the dummy instance we are going to use
            Customer loadedCustomer;

            // Explicitly state how the stubs should behave
            context.Stub(stub => stub.Customers).Return(customers);

            // Create a real instance of the CustomerManager that we want to put under test
            Managers.CustomerManager manager = new Managers.CustomerManager(context);

            // Act
            manager.Load(customerId, out loadedCustomer);

            // Assert
            context.AssertWasCalled(stub => { var temp = stub.Customers; });
            // Check the expected nature of the dummy intance
            Assert.IsNotNull(loadedCustomer);
            Assert.IsNotNull(loadedCustomer.ContactName);
            Assert.IsTrue(loadedCustomer.ContactName == "James PERSON");
        }

If we compare the two managers again (the manager that I had created in a previous blog posting depended on EF 1.0), we will see that the EF 2.0 instance actually contains lambda expressions to do the queries.

EF 1.0:


    /// <summary>
    /// Loads a customer instance with the relevant information from the database.
    /// </summary>
    /// <param name="i_customerId">The customerId of the customer data to be retrieved.</param>
    /// <param name="o_customer">The customer instance to be created.</param>
    public void Load(string i_customerId, out Customer o_customer)
    {
        if (string.IsNullOrEmpty(i_customerId))
        {
            throw new ArgumentException("Parameter cannot be null.", "i_customerId");
        }
        int numericVal;
        if (!int.TryParse(i_customerId, out numericVal))
        {
            throw new ArgumentException("Parameter cannot be non-numeric.", "i_customerId");
        }
        if (numericVal < 0 || numericVal > 9999)
        {
            throw new ArgumentOutOfRangeException("i_customerId");
        }

        m_customerRepository.Load(i_customerId, out o_customer);

        if (o_customer != null)
        {
            if (!string.IsNullOrEmpty(o_customer.ContactName) && o_customer.ContactName.Contains(" "))
            {
                o_customer.ContactName = o_customer.ContactName.Trim(' ');
                string[] names = o_customer.ContactName.Split(' ');
                if (names.Length > 1)
                {
                    names[names.Length - 1] = names[names.Length - 1].ToUpper();
                }
                o_customer.ContactName = string.Join(" ", names);
            }
        }
    }

EF 2.0:


    /// <summary>
    /// Loads a customer instance with the relevant information from the database.
    /// </summary>
    /// <param name="i_customerId">The customerId of the customer data to be retrieved.</param>
    /// <param name="o_customer">The customer instance to be created.</param>
    public void Load(string i_customerId, out Customer o_customer)
    {
        if (string.IsNullOrEmpty(i_customerId))
        {
            throw new ArgumentException("Parameter cannot be null.", "i_customerId");
        }
        int numericVal;
        if (!int.TryParse(i_customerId, out numericVal))
        {
            throw new ArgumentException("Parameter cannot be non-numeric.", "i_customerId");
        }
        if (numericVal < 0 || numericVal > 9999)
        {
            throw new ArgumentOutOfRangeException("i_customerId");
        }

        var customers = (from cus in _context.Customers
                         where cus.CustomerID == i_customerId
                         select cus);
        if (customers.Count() == 1)
        {
            o_customer = customers.Single<Customer>();
        }
        else
        {
            o_customer = null;
        }

        if (o_customer != null)
        {
            if (!string.IsNullOrEmpty(o_customer.ContactName) && o_customer.ContactName.Contains(" "))
            {
                o_customer.ContactName = o_customer.ContactName.Trim(' ');
                string[] names = o_customer.ContactName.Split(' ');
                if (names.Length > 1)
                {
                    names[names.Length - 1] = names[names.Length - 1].ToUpper();
                }
                o_customer.ContactName = string.Join(" ", names);
            }
        }
    }

In the second code, snippet, because I am calling straight to an instance of IObjectSet<Customer>, it could either be my mocked one or the actual Entity Framework instance, which looks like this (thanks to POCO binding):


    public class NorthwindContext : ObjectContext, INorthwindContext
    {

        public NorthwindContext()
            : base("name=NorthwindEntities", "NorthwindEntities")
        {
        }

        private ObjectSet<Order> _orders;
        private ObjectSet<Employee> _employees;
        private ObjectSet<Customer> _customers;

        #region INorthwindContext Members

        IObjectSet<Employee> INorthwindContext.Employees
        {
            get { return _employees ?? (_employees = CreateObjectSet<Employee>()); }
        }

        IObjectSet<Customer> INorthwindContext.Customers
        {
            get { return _customers ?? (_customers = CreateObjectSet<Customer>()); }
        }

        IObjectSet<Order> INorthwindContext.Orders
        {
            get { return _orders ?? (_orders = CreateObjectSet<Order>()); }
        }

        #endregion
    }

This means that when I run my code coverage for the EF 2.0 version, I will be hitting the true boundary between the entity and the model, thanks to a combination of POCO and the separation of concerns brought about by IObjectSet.

Ok, so there’s no kitchen sink – what would you do with it if there was?

  • Share/Bookmark

One way to use the Entity Framework on your legacy code

Following on the DI blog posts that I have been authoring lately, I wanted to discuss one possible method of stripping out the underlying data access layer (DAL) and introduce the Entity Framework from Microsoft. My intention is to write about how you would be able to use DI when introducing the new DAL.

Starting with what we already have.

In many cases there will be some form of data access layer manager class that will act as the proxy to client code when performing the request to the database and translating the returned query into “code entities”. This would be the ideal place to start the transition (obviously). Capitalizing on our earlier example of the NorthWind database, let’s assume that we have the following classes:

Base Classes

As you will see, we have two DAL related classes; EmployeeRepository and CustomerRepository. Both of these expose typical CRUD methods that we will refactor into interfaces. Once the principal methods have been extracted into interfaces then we can create the new client facing entities that will provide access to the DAL via the appropriate methods and functions:

Manager Classes

As you can see from the class diagram, each of the manager classes has two constructors; the first (parameter-less) constructor is the default and contains no code except for calling into the second constructor; the second (single parameter) constructor contains the assignation of a member variable to the associated repository interface:

  1. /// <summary>
  2.     /// Parameterless (Default) constructor
  3.     /// </summary>
  4.     public EmployeeDataManager() : this(null)
  5.     {
  6.     }
  7.  
  8.     /// <summary>
  9.     /// Parameterized constructor
  10.     /// </summary>
  11.     /// <param name="i_repository">The IEmployeeRepository instance to
  12.     /// be used.</param>
  13.     internal EmployeeDataManager(IEmployeeRepository i_repository)
  14.     {
  15.         m_repository = i_repository;
  16.     }

One important note to make and something that may or may not seem strange is the definition of the second constructor as internal as opposed to public. If you remember from a previous post, by defining the second constructor as internal and then exposing it only to the unit tests (via the assembly attribute InternalsVisibleTo) – this way when coding the clients of the manager, we will not place the onus of instantiating a repository on the client (unless you wish to do so).

Later on, once we have the DAL utilizing the Entity Framework in place, we can extend the assignation of the repository interface to also include the instantiation of our default DAL.

Incorporating the Entity Framework

The first stage is to create a suitable assembly where the Entity Framework related classes will reside and be referenced from. Therefore we could create an entity access assembly:

Pre Entity Framework

Now we can go through the steps of incorporating the Entity Framework:

  1. In the EntityAccess project, add a new “ADO.Net Entity Data Model” item:

    Stage 1
  2. In this example we want to create the model contents from the actual DB instance:

    Stage 2
  3. The next window of the Entity Data Model Wizard specifies the Data Connection that will be used. Depending on your requirements this will vary from situation to situation:

    Stage 3
  4. In this case we will create a new one for our purposes; click the “New Connection…” button to display the Connection Properties dialog (Fill-out the fields as appropriate to your purposes) and select the Server and the Database instance:

    Stage 4
  5. Once the Connection Properties have been configured, the appropriate information will appear:

    Stage 5
  6. Clicking the “Next >” button will take us to the “Choose Your Database Objects” window, where we can select the tables that we are interested in (seeing as it is such a small schema, we will select all tables in this example):
    Stage 6
  7. Once we have clicked on the “Finish” button the associated edmx file (XML file that defines an Entity Data Model) and it’s associated code behind have been generated:
    Stage 7 - a


    Test Stubs Dialog
  8. For consistency reasons (and personal preference) I normally change the default entity naming convention as follows, renaming the pluralized to singular:
    Stage 8 - a

    becomes

    Stage 8 - b


    Stage 8 - c

Now that we have added the Entity Framework into the solution we can set about incorporating the use of the appropriate repository interfaces (ICustomerRepository and IEmplyeeRepository).

Delving into the code generated when the Entity Data Model was generated (NorthWind.Designer.cs) we find that the class is defined as partial:

  1. /// <summary>
  2.     /// There are no comments for NorthwindSQLEntities in the schema.
  3.     /// </summary>
  4.     public partial class NorthwindSQLEntities : global::System.Data.Objects.ObjectContext
  5.     {
  6.      …
  7.     }

This means that we could use the same class to implement the two interfaces we already have defined:

Stage 9 - a

Unfortunately when we attempt this method of implementing the repository interfaces we encounter the following error on the first attempt at accessing the database via the entity data model:

Stage 9 - b

With this issue raised it is easier to sub-class the Entity Data Model generated class and implement the interfaces in the child class:

Stage 9 - c

Further digging around in the auto-generated Entity Data Model reveals the different overloads for the constructor:

  1. /// <summary>
  2.     /// Initializes a new NorthwindSQLEntities object using the
  3.     /// connection string found in the ‘NorthwindSQLEntities’ section
  4.     /// of the application configuration file.
  5.     /// </summary>
  6.     public NorthwindSQLEntities() :
  7.             base("name=NorthwindSQLEntities", "NorthwindSQLEntities")
  8.     {
  9.         this.OnContextCreated();
  10.     }
  11.     /// <summary>
  12.     /// Initialize a new NorthwindSQLEntities object.
  13.     /// </summary>
  14.     public NorthwindSQLEntities(string connectionString) :
  15.             base(connectionString, "NorthwindSQLEntities")
  16.     {
  17.         this.OnContextCreated();
  18.     }
  19.     /// <summary>
  20.     /// Initialize a new NorthwindSQLEntities object.
  21.     /// </summary>
  22.     public NorthwindSQLEntities(global::System.Data.EntityClient.EntityConnection connection) :
  23.             base(connection, "NorthwindSQLEntities")
  24.     {
  25.         this.OnContextCreated();
  26.     }

With this in mind we can create a constructor that takes 4 parameters that can be used to generate the appropriate connection string:

  1. /// <summary>
  2.     /// Creates a new NorthwindEntityContext.
  3.     /// This class will be the handler for all CRUD operations
  4.     /// perfomed by the EntityAccess layer.
  5.     /// A connection is created from this constructor.
  6.     /// </summary>
  7.     public NorthwindSQLEntities(
  8.         string i_serverName,
  9.         string i_catalogName,
  10.         string i_user,
  11.         string i_pswd)
  12.             : base(BuildConnectionString(
  13.                 i_serverName,
  14.                 i_catalogName,
  15.                 i_user,
  16.                 i_pswd))
  17.         {
  18.            
  19.         }

The BuildConnectionString function would construct the appropriate connection string as follows:

  1. private static string BuildConnectionString(string i_serverName, string i_catalogName, string i_user, string i_pswd)
  2.     {
  3.         string serverName = Environment.MachineName;
  4.         if (!string.IsNullOrEmpty(i_serverName))
  5.             serverName = i_serverName;
  6.         string catalogName = "NorthwindSQL";
  7.         if (!string.IsNullOrEmpty(i_catalogName))
  8.             catalogName = i_catalogName;
  9.  
  10.         string AdoConnectionString = string.Empty;
  11.         if (!string.IsNullOrEmpty(i_user))
  12.         {
  13.             AdoConnectionString = string.Format(
  14.             "Data Source={0};Initial Catalog={1};Integrated Security=False;MultipleActiveResultSets=True;Uid={2};Pwd={3}",
  15.             serverName, catalogName, i_user, i_pswd);
  16.         }
  17.         else
  18.         {
  19.             AdoConnectionString = string.Format(
  20.                 "Data Source={0};Initial Catalog={1};Integrated Security=True;MultipleActiveResultSets=True",
  21.                 serverName, catalogName);
  22.         }
  23.         return string.Format(
  24.             "metadata=res://*/{0}.csdl|res://*/{0}.ssdl|res://*/{0}.msl;provider=System.Data.SqlClient;provider connection string=\";{1}\";",
  25.             EntityModelName, AdoConnectionString);
  26.     }

The Entity Framework provides the appropriate mapping between the Storage Model (Database) and the Conceptual Model (entities), however, in order to be able to implement Dependency Injection we need to maintain (or create) a disconnected set of implementation classes that are agnostic to the underlying repository (be it Entity Framework or any other data access model, such as NHibernate, etc.).

Therefore the CRUD methods that we have exposed through our original interfaces, in the Entity Framework domain, would provide a certain amount of “translation” from the disconnected entity type to the “connected” (EDM) type:

  1. using BaseCustomer = DiDemo.BaseData.Entities.Customer;
  2. using DiDemo.BaseData.Interfaces;
  3.  
  4. namespace DiDemo.EntityAccess
  5. {
  6.     public partial class NorthwindSQLEntities :
  7.         ICustomerRepository, IEmployeeRepository
  8.     {
  9.     /// <summary>
  10.     /// Insert a new Customer instance into the Database.
  11.     /// </summary>
  12.     /// <param name="i_customer">
  13.     /// The Customer instance to be inserted.
  14.     /// </param>
  15.     public void Insert(BaseCustomer i_customer)
  16.     {
  17.         Customer customer = new Customer()
  18.             {
  19.                 Address = i_customer.Address,
  20.                 City = i_customer.City,
  21.                 CompanyName = i_customer.CompanyName,
  22.                 ContactName = i_customer.ContactName,
  23.                 ContactTitle = i_customer.ContactTitle,
  24.                 Country = i_customer.Country,
  25.                 CustomerID = i_customer.CustomerID,
  26.                 Fax = i_customer.Fax,
  27.                 Orders = new EntityCollection<Order>(),
  28.                 Phone = i_customer.Phone,
  29.                 PostalCode = i_customer.PostalCode,
  30.                 Region = i_customer.Region
  31.             };
  32.         this.AddToCustomerSet(customer);
  33.         this.SaveChanges();
  34.     }

Unit Testing

Now that we have the underlying Data Access Layer sorted out, time to move on to the reason for this blog posting – Unit Testing.

Obviously the very basic CRUD methods and functions do not provide any head banging issues when it comes to unit testing, however, suppose there a function returned an IQueryable instance? It could possibly be conceived that such a method existed as follows:

  1. /// <summary>
  2.     /// Returns a List of Customer instances
  3.     /// </summary>
  4.     /// <returns>List containing all Customer instances.</returns>
  5.     public List<BaseCustomer> LoadAllCustomers()
  6.     {
  7.         return Query_LoadAllCustomers().ToList();
  8.     }
  9.  
  10.     /// <summary>
  11.     /// Returns an IQueryable for the Customers entity set.
  12.     /// </summary>
  13.     /// <returns>IQueryable of the customer enitity set.</returns>
  14.     public IQueryable<BaseCustomer> Query_LoadAllCustomers()
  15.     {
  16.         return (from query in CustomerSet
  17.                 select new BaseCustomer()
  18.                 {
  19.                     Address = query.Address,
  20.                     City = query.City,
  21.                     CompanyName = query.CompanyName,
  22.                     ContactName = query.ContactName,
  23.                     ContactTitle = query.ContactTitle,
  24.                     Country = query.Country,
  25.                     CustomerID = query.CustomerID,
  26.                     Fax = query.Fax,
  27.                     Phone = query.Phone,
  28.                     PostalCode = query.PostalCode,
  29.                     Region = query.Region
  30.                 });
  31.     }

Surprisingly enough it is not that difficult to create the unit test for such a method in the Manager class. Seeing as we have successfully done the dependency injection prior to creating the entity framework related classes, all we are actually doing is writing the test for the manager class by mocking the repository interface:

  1. [TestMethod]
  2.     public void TestIQueryableOnEntity()
  3.     {
  4.         // Create the mock instance
  5.         IEmployeeRepository eConnect = m_mockRepository.DynamicMock<IEmployeeRepository>();
  6.  
  7.         // Here we create an actual instance
  8.         IQueryable<Employee> mockedCollection;
  9.  
  10.         // Setup a dummy list that will be filtered, queried, etc
  11.         List<Employee> employeeList = CreateEmployeList();
  12.         mockedCollection = employeeList.AsQueryable();
  13.  
  14.         // Now we set our expectations
  15.         Expect.Call(eConnect.Query_LoadAllEmployees()).Return(mockedCollection);
  16.  
  17.         // Replay our expectations
  18.         m_mockRepository.ReplayAll();
  19.  
  20.         // Create a real instance of the EmloyeeConnector that we want to put under test
  21.         EmployeeManager manager = new EmployeeManager(eConnect);
  22.  
  23.         List<Employee> employees = manager.Query_LoadAllEmployees().ToList();
  24.  
  25.         Assert.IsNotNull(employees);
  26.  
  27.         Assert.IsTrue(employees.Count == employeeList.Count);
  28.     }

The secret is in the AsQueryable method on the List instance. By doing this we can simulate the behavior of the IQueryable function on our Entity Data Model.

  • Share/Bookmark

What’s in a name?

Google “Pex” and what do you expect to find? According to Wikipedia:

“Cross-linked polyethylene, commonly abbreviated PEX or XLPE, is a form of polyethylene with cross-links.”

That’s not really the definition I was hoping for, so if we qualify the search with “Microsoft” then we have a better chance of encountering a more meaningful software related defintion:

“Pex (Program EXploration) produces a traditional unit test suite with high code coverage. A parameterized unit test is simply a method that takes parameters, calls the code under test, and states assertions. Given a parameterized unit test written in a .NET language, Pex automatically produces a small unit test suite with high code and assertion coverage. To do so, Pex performs a systematic white box program analysis.”

Well, now we have got that cleared up, let’s have a look at what we can do with it.

For a start, the most powerful aspect of Pex is the white box analysis that it performs on an existing unit of code. This analysis will create the appropriate boundary test (as best as it can). The generation of test code is not extensive; it covers the simple cases and where complex data type are used, the developer will most likely still have to fall back on utilizing test methods such as mocking.

Part of the secret of getting Pex to work your code properly is to provide some form of Parameterized Unit Test to get it started. Another important factor is to use the Stubs Lightweight Framework (also a research project from Microsoft) to create appropriate stubs for the Parameterized Unit Tests. Both methods can be generated quite easily; however a few tweaks are required to get it just right.

In order to illustrate the work involved we shall revisit the previous example of one of the Managers (either EmployeeManager or CustomerManager). The following walkthroughs assume that you have Pex installed and that you have either Visual Studio Test edition or Team edition installed.

How it is done using defaults…

In the first stage we need to instruct the assembly being tested that it will give the new unit test assembly access to the internal methods and properties (see my previous post):

  1. [assembly: InternalsVisibleTo("DiDemo.Managers.Tests")]

The second stage is to create the Unit Test project that will “house” the Pex generated unit Tests. The easiest way to do this is to use the Pex auto-generation functionality from the Code Context menu:

  1. Right click the class name that will have the unit tests generated (in our case CustomerManager) and select the Pex->Create Parameterized Unit Test Stubs:

    Generate Test Stubs
  2. Configure the Unit Test project that you want to target the auto-generated code to (in this case we will select from the drop down combo box) and click Ok when you are ready:

    Test Stubs Dialog
  3. Specify (if you wish) the location of the new Test project and click OK:

    Test Stubs Dialog
  4. The result will be the generation of the new Unit Test project complete with auto-generated Stubs and Parameterized Unit Test Stubs:

    Generated Unit Tests

Having a quick look at what is generated, we see that the stubx file is the configuration xml for the Microsoft Stubs engine that indicates which assembly we are generating the stubs from – thereby creating the stubs designer file:

Generated Stubs

As we will see later on, the stubs that are generated in this “default” manner might not be exactly what we want, although the concept is going to come in handy.

Next is the auto generated parameterized unit test stubs. These methods are intended to be used by Pex to generate the unit test methods when the analysis is run. In their current format they do little but to serve as place holders:

Generated Test Methods

At this stage, as an educational exercise, we can run the Pex Explorations to see what gets thrown up:

Run Pex Explorations

Looking through the results there is one glaring issue and that is the fact that the way we have created the architecture of the managers (using Dependency Injection and having default behavior); we have inadvertently generated integration tests (the clue is in the fact that we are seeing SqlExceptions – this means that we have also explored the underlying data access layer, which we had tried so hard to inject the dependency for:

First Results Pex Explorations

The thought through way…

In my mind we don’t want to generate stubs of the classes that we are actually testing, we want to generate stubs of the interfaces that we are injecting into the classes we are testing – a subtle difference, but nevertheless one that is important.

Therefore, strip out the constructor tests (parameter-less and single DI parametered constructor):

Delete Constructor Tests

After those test methods are removed, delete the Manager stubs (we aren’t interested in stubbing out the class we are testing):

Delete Stubs

Finally we want to generate the stubs for the Interfaces, so we need to create a stub of the BaseData assembly:

Generate Data Stubs

Now that the stubs are generated, we can go about changing the parameterized test methods to fit our own purposes. Taking the first method Delete, we make the changes to the method in such a way that the method itself creates the class instance we want to test and the parameter provides us with the boundary conditions. This means that our code changes from this:

  1. /// <summary>Test stub for Delete(Customer)</summary>
  2. [PexMethod]
  3. public void Delete([PexAssumeUnderTest]CustomerManager target, Customer i_customer)
  4. {
  5.     // TODO: add assertions to method
  6.     // CustomerManagerTest.Delete(CustomerManager, Customer)
  7.     target.Delete(i_customer);
  8. }

to this:

  1. /// <summary>Test stub for Delete(Customer)</summary>
  2. [PexMethod]
  3. public void Delete(Customer i_customer)
  4. {
  5.     // Create a stub instance of the ICustomerRepository
  6.     var stub = new SICustomerRepository();
  7.     stub.Delete = (a) => { };
  8.     ICustomerRepository repository = stub;
  9.     // Create a real instance of the CustomerManager that we want
  10.     // to put under test
  11.     CustomerManager manager = new CustomerManager(repository);
  12.     manager.Delete(i_customer);
  13. }

Once all of the parameterized unit tests are prepared we can run the Pex Explorations again:

Run Pex Explorations

The result this time is quite different to what we had previously with the outcome being more conclusive than the first. Upon inspection we actually find some test scenarios that we didn’t cover in our code:

Second Results Pex Explorations

The general idea is to continue to adjust the code of your class to make sure that all of the test cases are handled correctly until you can achieve, as far as possible, test case completeness:

Completed Test Scenario

The next stage is to run the tests to see what the code coverage is:

Completed Code Coverage

You will see that we didn’t get 100% code coverage because of the method “<LoadAllCustomers>b__0(class DiDemo.BaseData.Entities.Customer,class DiDemo.BaseData.Entities.Customer)”;which is the following area of code:

Last five percent

Conclusion

What is on offer by using Pex is quite astounding, but by no means bullet proof. There are still cases that you will want to write your own test method to try to reach the nirvana of 100% code coverage; however what Pex does do is to take care of the majority of cases that you would grudgingly have to knock out by hand.

The other niggling issue in my mind is the fact that the stubs have to be re-generated anytime there is a change made to a dependant class, which might seem like nit-picking, it is still something that could be overlooked during development – thereby rendering the unit test as unreliable.

On the whole I am quite impressed by what is on offer and I could foresee it’s use when the wider .NET development community starts to walk around and kick the tires a bit more, maybe even take it out for a few laps.

  • Share/Bookmark

Whilst doing further research into the topic of Dependency Injection and Rhino Mocks I came across a blog entry that gave me a certain amount of food for thought. The article spoke about using the friend assembly directive in C# and how you could effectively hide the injected constructor from all but your unit test assembly. From MSDN:

The friend assemblies feature allows you to access internal members; private types and private members will remain inaccessible.
To give an assembly (assembly B) access to another assembly’s (assembly A’s) internal types and members, use the InternalsVisibleToAttribute attribute in assembly A.

Revisiting the code from the examples used in the previous articles we would need to add the attribute to the class declaration so that the Unit Test assembly “BlogSamples.UnitTest” would be allowed access to the internal constructor:

  1. /// <summary>
  2. /// Single parameter constructor using dependency injection pattern.
  3. /// </summary>
  4. /// <param name="i_employeeRepository">An object instance that implements the IEmployeeRepository interface.</param>
  5. internal EmployeeManager(IEmployeeRepository i_employeeRepository)
  6. {
  7.     Initialize(i_employeeRepository);
  8. }

We would also have to add the InternalsVisibleTo attribute declaration to the AssemblyInfo.cs file:

  1. [assembly: InternalsVisibleTo("BlogSamples.UnitTest")]

This would have the effect of allowing the “BlogSamples.UnitTest” assembly access to all internal members of the “BlogSamples.DbConnector” assembly. This can be easily seen when utilizing the intellisense whist within the code of a “BlogSamples.UnitTest” class:

Visible Internal Constructor

Whilst any other assembly accessing the members of “BlogSamples.DbConnector” would only see the parameter-less constructor:

Default Constructor only

This would mean that the existing client’s remain un-changed, whilst future development will not be able to use the Constructor Injection design of the EmployeeConnector class as it would be hidden via the internal directive.

  • Share/Bookmark

In continuation with the Dependency Injection entry of my previous blog, now we look at how we can leverage the work we did to use it with a mocking framework to perform proper unit testing.

There are numerous blogs and articles about different Mocking frameworks and after taking a couple of them around the block and kicking the tires I settled on RhinoMocks as the best fit for my needs. I put together a little table to try and capture my thought process on choosing the appropriate framework and although this is not an extensive list it met my needs at the time:

  Ease of use Cost Likes Dislikes Conclusion
RhinoMocks Relatively easy because it’s strongly-typed, which makes the syntax great and"safe". Free Strongly typed instancing – no need to use string references. None so far "Allows for generating a mock object of a class without the interface a requirement. What is powerful about this technique, is that you can request Rhino.Mock to create a mock object of a class (even something like System.Net.WebClient) and then pass that mock object into the implementation of your class.

Now any calls to System.Net.WebClient will be to your mock object even though the target library was compiled to use System.Net.WebClient.

Furthermore, the setting up of method call expectations is compiled, rather than just string names for the methods."
NMock Use of strings to call property methods / normal methods. Free Pales to insignificance in contrast to RhinoMocks or TypeMock Need to use string declarations for instancing. "Requires the object to be mocked so support an interface. Mock objects are generated at runtime to implement the interface. Programmatically you inject method implementations on the mock object so that it expects certain calls and returns values for those calls. This works great until the class you want to mock does not implement an interface."
TypeMock Extremely easy to implement mocking because it uses the .NET framework profiler API to monitor an application’s execution. When a method is called, the CLR notifies Isolator. The framework can then return mocked values and override the original code completely. Expensive The fact that it "plugs-in" to the CLR and captures type references, means that no code changes need to be done on legacy components. Prohibitively Expensive. "Allows for the runtime generation of type objects on the fly within the target project, not just within the test. As a result, you can identify the types you wish TypeMock engine to intercept and then, whenever the target library instantiates those objects, a mock object will be created instead."


If it were not for the pricing this would be the choice (10 out of 10):

Complete Bundle License Per User (12 months): $749.00

Complete Bundle Build Server License (5 VM): $1,999.00

ASP.NET Bundle License Per User (12 months): $599.00

ASP .NET Bundle Build Server License (5 VM): $1,449.00

So what is mocking?

Well, for those readers that are not familiar with mocking it can be summed up with a reference to Martin Fowler in his Mock’s aren’t Stubs post

Mocks are objects pre-programmed with expectations which form a specification of the calls they are expected to receive.

Whilst doing my research into the use of Mocking Frameworks and what I wanted to get out of them I came across a few references to “Isolation Frameworks” that seemed to be used on top of the reference to Mocking Frameworks and the idea is effectively that you use the mocking framework of your choice to isolate the unit under test by specifying the expected behavior of the mocked object. We are still mocking, but with in the context of testing an acute code path of a particular class.

How does it fit in with the example?

In my previous blog, I introduced the very basic example of dependency injection to illustrate the idea behind isolating the dependencies in order to easily “injection” an alternative. Now that we have the ability to inject an alternative, we’ll create mock instances of those dependencies and use those instead of the real ones.

As a reminder, here is the definition of the IEmployeeConnector interface that we created when setting up the Dependency Injection in the EmployeeConnector class:

  1. public interface IEmployeeRepository
  2. {
  3.     /// <summary>
  4.     /// A string containing the connection details for the underlying data repository resource.
  5.     /// </summary>
  6.     string ConnectionString { get; set; }
  7.  
  8.     /// <summary>
  9.     /// Inserts a new Employee instance in to the data repository.
  10.     /// </summary>
  11.     /// <param name="i_employee">The Employee instance to insert.</param>
  12.     void Insert(Employee i_employee);
  13.  
  14.     /// <summary>
  15.     /// Loads (retrieves) an Employee instance from the data repository.
  16.     /// </summary>
  17.     /// <param name="i_employeeId">The unique identifier fro the Employee instance.</param>
  18.     /// <param name="o_employee">The Employee instance retrieved.</param>
  19.     void Load(int i_employeeId, out Employee o_employee);
  20.  
  21.     /// <summary>
  22.     /// Updates an existing Employee instance in the data repository.
  23.     /// </summary>
  24.     /// <param name="i_employee">The Employee instance to update.</param>
  25.     void Update(Employee i_employee);
  26.  
  27.     /// <summary>
  28.     /// Updates an existing Employee instance from the data repository.
  29.     /// </summary>
  30.     /// <param name="i_employee">The Employee instance to delete.</param>
  31.     void Delete(Employee i_employee);
  32.  
  33.     /// <summary>
  34.     /// Retrieves all employee instances  from the data repository.
  35.     /// </summary>
  36.     /// <returns>List of EMployee instances retrieved from the data repository.</returns>
  37.     List<Employee> LoadAllEmployees();
  38. }

With this in mind, we can then test the functionality of the LoadAllEmployees function:

  1. /// <summary>
  2. /// Retruns a sorted list of all employees. Sorted by Last Name.
  3. /// </summary>
  4. /// <returns>List of sorted employees.</returns>
  5. public List<Employee> LoadAllEmployees()
  6. {
  7.     List<Employee> retVal = m_employeeRepository.LoadAllEmployees();
  8.     if (retVal.Count > 0)
  9.     {
  10.         retVal.Sort(delegate(Employee e1, Employee e2)
  11.         {
  12.             return e1.LastName.CompareTo(e2.LastName);
  13.         });
  14.     }
  15.     return retVal;
  16. }

This then implies that we need to create a mock instance of the IEmployeeConnector that will be passed into the constructor of the EmployeeConnector class. The following MSTest method provides an example of how we can do this:

  1. [TestMethod]
  2. public void TestGetSortedEmployeeList()
  3. {
  4.     // Create the mock instance
  5.     IEmployeeRepository eConnect = m_mockRepository.DynamicMock<IEmployeeRepository>();
  6.  
  7.     // Here we create an actual instance
  8.     List<Employee> filledCollection;
  9.     FillCollection(ObjectInstances.FilledInstance, out filledCollection);
  10.  
  11.     // Now we set our expectations
  12.     Expect.Call(eConnect.LoadAllEmployees()).Return(filledCollection);
  13.  
  14.     // Replay our expectations
  15.     m_mockRepository.ReplayAll();
  16.  
  17.     // Create a real instance of the EmloyeeConnector that we want to put under test
  18.     EmployeeManager manager = new EmployeeManager(eConnect);
  19.  
  20.     List<Employee> employees = manager.LoadAllEmployees();
  21.  
  22.     Assert.IsNotNull(employees);
  23.  
  24.     Assert.IsTrue(employees.Count > 0);
  25.  
  26.     Assert.IsTrue(employees[0].LastName == "Anderson");
  27. }

This test method will test the Sort functionality of the LoadAllEmployees function on the EmployeeConnector instance in isolation, because we have told the mocking framework exactly how we want it to behave with the Expect.Call() function.

When the method does get called within the LoadAllEmployees of the EmployerConnector method the RhinoMocks framework will pass back the filledCollection instance that we had constructed:

  1. Expect.Call(eConnect.LoadAllEmployees()).Return(filledCollection);

As a brief note, the Test utility method FillCollection() will fill the passed in List collection with dummy data that the Test method can then check against in the Assert statements:

  1. private static void FillCollection(ObjectInstances instanceType, out List<Employee> filledCollection)
  2. {
  3.     filledCollection = new List<Employee>();
  4.     if (instanceType == ObjectInstances.FilledInstance)
  5.     {
  6.         Employee instance = new Employee();
  7.         instance.Address = "123 Road";
  8.         instance.BirthDate = new DateTime(1975, 3, 15);
  9.         instance.City = "Acity";
  10.         instance.Country = "Acountry";
  11.         instance.EmployeeID = 1234;
  12.         instance.Extension = "5678";
  13.         instance.FirstName = "John";
  14.         instance.HireDate = new DateTime(2005, 5, 21);
  15.         instance.HomePhone = string.Empty;
  16.         instance.LastName = "Doe";
  17.         instance.Notes = string.Empty;
  18.         instance.Photo = string.Empty;
  19.         instance.PostalCode = "01234";
  20.         instance.Region = "Aregion";
  21.         instance.ReportsTo = 1;
  22.         instance.Title = "General Whatsit";
  23.         instance.TitleOfCourtesy = "Mr.";
  24.         filledCollection.Add(instance);
  25.  
  26.         instance = new Employee();
  27.         instance.Address = "123 Street";
  28.         instance.BirthDate = new DateTime(1965, 6, 24);
  29.         instance.City = "Acity";
  30.         instance.Country = "Acountry";
  31.         instance.EmployeeID = 5678;
  32.         instance.Extension = "2003";
  33.         instance.FirstName = "Samantha";
  34.         instance.HireDate = new DateTime(2007, 6, 24);
  35.         instance.HomePhone = string.Empty;
  36.         instance.LastName = "Anderson";
  37.         instance.Notes = string.Empty;
  38.         instance.Photo = string.Empty;
  39.         instance.PostalCode = "01234";
  40.         instance.Region = "Aregion";
  41.         instance.ReportsTo = 1;
  42.         instance.Title = "General Whatchamacallit";
  43.         instance.TitleOfCourtesy = "Ms.";
  44.         filledCollection.Add(instance);
  45.  
  46.         instance = new Employee();
  47.         instance.Address = "405 Avenue";
  48.         instance.BirthDate = new DateTime(1980, 2, 10);
  49.         instance.City = "Acity";
  50.         instance.Country = "Acountry";
  51.         instance.EmployeeID = 9876;
  52.         instance.Extension = "0987";
  53.         instance.FirstName = "Donna";
  54.         instance.HireDate = new DateTime(2000, 4, 18);
  55.         instance.HomePhone = string.Empty;
  56.         instance.LastName = "Kebab";
  57.         instance.Notes = string.Empty;
  58.         instance.Photo = string.Empty;
  59.         instance.PostalCode = "01234";
  60.         instance.Region = "Aregion";
  61.         instance.ReportsTo = 1;
  62.         instance.Title = "Manager";
  63.         instance.TitleOfCourtesy = "Mrs.";
  64.         filledCollection.Add(instance);
  65.     }
  66. }

Visual Studio Test Edition

One of the wonders of the Visual Studio Test Edition is the fact that you can run the MSTests and also specify the Assembly that you want to perform code-coverage:

Visual Studio Code Coverage Dialog

Once this is done, then when you run the MSTest you can view the code paths that were covered by the test (with highlighting):

Code Coverage Results - Covered

And also those code paths that were not covered (with highlighting):

Code Coverage Results - Not covered

  • Share/Bookmark

On numerous projects that I have worked on, the question has always arisen on how to tackle the issue of writing unit tests for existing components that have “been around the block a few times”. Invariably the answer was to only write unit tests for the new functionality and leave what has existed “for eons” well alone – I mean, it works doesn’t it? That may be the case, however it is not long before there are changes required in one area that could well impact on “old faithful”. The other reality, in my experience, the people who originally developed the “solid” code have long since left and now the development team is “aware” of what the code does, but few will dare change it for risk of breaking it. I’ve seen some serious scaffolding go on around existing code for fear of breaking the underlying functionality.

The answer is simple and, when seen from a pragmatic point of view, quite necessary – write the unit tests for that code. It will not only be an education for the developer writing the unit test to really understand the code that is being tested, but could also lead to improving the coupling by way of using Dependency Injection.

The example I have dreamt up here is by no means problematic (nor is it a work of art), the intention is to illustrate some of the methods of actually decoupling the code and using Dependency Injection.

Before going any further we need to mention the two types of Dependency Injection that most people are familiar with: Constructor Injection and Setter Injection.

Constructor Injection

As the name implies, is where the dependency is injected via the constructor. Typically an interface is passed in to the constructor as a parameter and is used to set a member variable:

  1. public CustomerManager(ICustomerRepository i_customerRepository)
  2. {
  3.     m_customerRepository = i_customerRepository;
  4. }

As you can see the internal member variable is being set to an instance of an object that implements the appropriate interface. As for the introduction of a null, there are several approaches on this:

  • Detect the null and instantiate a related “Null” type (not a null, but a minimal class that implements the expected interface).
  • Detect the null and instantiate a known, default type.
  • Detect the null and throw an exception.

In the first two cases we would not, strictly speaking, be able to write unit tests for as they would run the risk of changing the test into an integration test – imagine that the known default type was actually the next layer that communicated directly with the DB, you will inadvertently employ the test method that we are trying so hard to avoid. The third case would be testable, but could work out to be impractical in production code – there are instances where it is better to instantiate a default instance and therefore minimize the effect on production code. With this in mind, let’s return to the example previously:

  1. public CustomerManager()
  2. {
  3.     Initialize(null);
  4. }
  5.  
  6. public CustomerManager(ICustomerRepository i_customerRepository)
  7. {
  8.     Initialize(i_customerRepository);
  9. }
  10.  
  11. private ICustomerRepository m_customerRepository;
  12.  
  13. private void Initialize(ICustomerRepository i_customerRepository)
  14. {
  15.     m_customerRepository = i_customerRepository ??
  16.         new BlogSamples.SqlRepository.CustomerRepository();
  17. }

Setter Injection

Another way of injecting dependency would be to inject via the set method of a property on the object.

Using the example above, consider setting the ICustomerRepository instance via a property instead of the constructor:

  1. private ICustomerRepository m_customerRepository;
  2.  
  3. public ICustomerRepository Repository
  4. {
  5.     get
  6.     {
  7.         if (m_customerRepository == null)
  8.         {
  9.             m_customerRepository =
  10.                 new BlogSamples.SqlRepository.CustomerRepository();
  11.         }
  12.         return m_customerRepository;
  13.     }
  14.     set
  15.     {
  16.         m_customerRepository = value ??
  17.             new BlogSamples.SqlRepository.CustomerRepository();
  18.     }
  19. }

In this example I have taken a similar stance to what was mentioned previously in the constructor injection scenario. I have treated a null instance with a default instantiation. In this case I do have my doubts as to whether it is the right approach. As soon as we start to introduce default behavior we are immediately “roping off” an area that cannot be touched by proper unit testing (i.e. the idea of isolating the class entirely from it’s resources and injection those dependencies from outside). My only argument in this method’s defense is the fact that if it was true legacy code, I would need to be very careful of the client’s that use the class I am working with – far worse than not testing an a smaller part of the code would be to break existing functionality, from the client code point of view.

In either scenario (Constructor Injection or Setter Injection) we are forcing the decoupling to occur via passing in the dependency from outside the object instance.

The best method of deciding what needs to be injected is to look at what would be implied when creating an instance of a class or calling a static method from within the class in question. If the call to the method or instantiation of a type returns a simple type that did not require any complex business logic or external resources (such as a Database or config file) then chances are you are pretty safe. If, however, an external resource was accessed, then it is an ideal candidate for dependency injection and either method described previously could be used.

Example code

The example that I have prepared involves two classes, CustomerManager and EmployeeManager. Each one accesses the Database instance of the NorthWind DB (on a SQL Server instance) and each one expose typical CRUD methods. The attached zip file contain the before and after of the changes that were made to the code in order to achieve a more de-coupled class and introduce dependency injection (Base – original code; UsingDi – employing dependency injection).

The first phase was to extract the signatures of the appropriate methods and put them in to an interface (ICustomerRepository and IEmployeeRepository).

  1. public interface ICustomerRepository
  2. {
  3.     string ConnectionString { get; set; }
  4.  
  5.     void Insert(Customer i_customer);
  6.  
  7.     void Load(int i_customerId, out Customer o_customer);
  8.  
  9.     void Update(Customer i_customer);
  10.  
  11.     void Delete(Customer i_customer);
  12.  
  13.     List LoadAllCustomers();
  14. }

Once this was done, I then set about refactoring the code that accessed the DB into it’s own assembly and class; implementing the new interface. This then meant that the original CustomerManager class method’s were reduced to essentially to everything except the database access code (in this case it turned out to be a straight call through, however you get the general idea of what the aim of the exercise was):

Before:

  1. public void Insert(Customer i_customer)
  2. {
  3.     using (System.Data.SqlClient.SqlConnection connection = new SqlConnection(this.ConnectionString))
  4.     {
  5.         using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand())
  6.         {
  7.             cmd.Connection = connection;
  8.             cmd.CommandText =
  9.                 "INSERT INTO Customers (CustomerID, CompanyName, ContactName, ContactTitle, " +
  10.                 "Address, City, Region, PostalCode, Country, Phone, Fax) VALUES " +
  11.                 "(@CustomerID_PARAMS, @CompanyName_PARAMS, @ContactName_PARAMS, " +
  12.                 "@ContactTitle_PARAMS, @Address_PARAMS, @City_PARAMS, @Region_PARAMS, " +
  13.                 "@PostalCode_PARAMS, @Country_PARAMS, @Phone_PARAMS, @Fax_PARAMS)";
  14.             cmd.Parameters.AddWithValue("@CustomerID_PARAM", i_customer.CustomerID);
  15.             cmd.Parameters.AddWithValue("@CompanyName_PARAM", i_customer.CompanyName);
  16.             cmd.Parameters.AddWithValue("@ContactName_PARAM", i_customer.ContactName);
  17.             cmd.Parameters.AddWithValue("@ContactTitle_PARAM", i_customer.ContactTitle);
  18.             cmd.Parameters.AddWithValue("@Address_PARAM", i_customer.Address);
  19.             cmd.Parameters.AddWithValue("@City_PARAM", i_customer.City);
  20.             cmd.Parameters.AddWithValue("@Region_PARAM", i_customer.Region);
  21.             cmd.Parameters.AddWithValue("@PostalCode_PARAM", i_customer.PostalCode);
  22.             cmd.Parameters.AddWithValue("@Country_PARAM", i_customer.Country);
  23.             cmd.Parameters.AddWithValue("@Phone_PARAM", i_customer.Phone);
  24.             cmd.Parameters.AddWithValue("@Fax_PARAM", i_customer.Fax);
  25.  
  26.             connection.Open();
  27.  
  28.             cmd.ExecuteNonQuery();
  29.  
  30.             if (connection.State == ConnectionState.Open)
  31.             {
  32.                 connection.Close();
  33.             }
  34.         }
  35.     }
  36. }

After:

  1. public void Insert(Customer i_customer)
  2. {
  3.     m_customerRepository.Insert(i_customer);
  4. }

Although the example does not show any advantage in factoring out the code to a separate assembly (effectively the class has become so lightweight that it is simply calling through to the dependant instance), it does serve to show how the resource intensive code (i.e. the code that accesses the Database) can be removed to leave the code that can be tested in isolation without the need for accessing the underlying resources.

A small note on refactoring.

I use JetBrains ReSharper in Visual Studio 2008 and since the first day I have had it installed, it has been a real godsend to my code. Apart from all of the syntax highlighting and helpful hints on problematic code, one of the best features is the refactoring. Whilst preparing the code for this blog entry I had to pull out the methods from the original Connector class into an interface. At first I was “horrified” at the prospect of cutting, pasting and pruning the code as I was unsure what I would have been left out or added.

Step in ReSharper. By right clicking on the Method name I get access to the following context menu:

ReSharper Context Menu

ReSharper Context Menu

When I select extract interfaces I get the following dialog, notice how you can even state where the code for the interface gets pulled out to:

ReSharper Extract Interface Dialog

ReSharper Extract Interface Dialog

In the next blog entry I will illustrate how we can use mocking to illustrate how we would go about doing the unit testing.

  • Share/Bookmark

Although I have no concrete numbers, there are numerous software development projects that are well intentioned when it comes to unit testing; however their actual implementation of unit testing falls woefully short of what is considered proper / correct unit testing.

Many times it is because of time constraints and is more of a case of ticking a task as done, when in actual fact what has happened is that legacy code has made it prohibitively time consuming to do correct unit testing. For the most part, teams are doing light integration testing by using existing components to test the class that they are supposedly writing the unit test for. Other times it may be the lack of understanding of what Unit Testing really implies. Quite often the developer will write the unit test with the intention of only testing the class that they are interested in, but have not thought about the way in which the class needs to be isolated in order to perform the testing. The most common culprit causing teams to fall short of correct unit testing are classes that are dependant on database connectivity. I have seen so many cases where the design of the class has been left untouched with the belief that because the tests are concentrated on the class, then it is considered unit testing. In most of the cases I have seen, Unit Testing has been an activity that is planned for towards the end of the implementation and therefore is the activity that receives the least amount of attention (if at all).

Well sadly, despite those best efforts and intentions, it is not proper unit testing. At the end of the day, it turns out that the class in question is not the only unit being tested; quite often it is also the data access layer that comes under test as well.

I think we have all fallen in to this trap, I myself have been guilty of it and I doubt very much there isn’t a single individual that hasn’t fallen in to this “lie” at one time or another. A unit test needs to be just that; testing one unit of code. The code paths that you are testing must reach down to the boundaries of the next class or resource, without actually traversing into that class or resource. I am sure that those of us who have been down this route will being nodding their heads (guiltily) and asking themselves the same question that I did “How can you test a class without data?”

This is true; you do need data for your tests. But it needs to be controlled data, data that the test generates and you know exactly what the outcome of that test is going to be. Thinking about it now, I was very fortunate in my early career to have the opportunity to work for a company that produces both software AND hardware upon which the software was to operate. In the same building we had software and hardware engineers, it was the first time I had the opportunity to see for myself a real test bed and test harnesses – and I’m not talking about the software type either, I am talking about true, honest to goodness test harnesses. The machine testing the PCB (printed circuit board) actually had probes that poked down onto the board and “injected” signals onto the circuits at key points to test the appropriate reaction of the circuits under test. Although this analogy does not truly reflect unit testing as there were points in the circuit that would have meant actually testing the signal across one or two other components, it serves as a useful point of reflection.

The data needs to be injected into the class and should only affect the class under test. Otherwise, how can you tell that the failure of the test is not actually related to an underlying component or some issue with database connectivity? For those of us working in the object driven development environment, we have had the answer staring us in the face all the time. Dependency Injection!

It might sound like a buzzword, but DI has been around for some time. It is based on the use of Interfaces. Yup, that’s what I said – Interfaces. Although the excessive use of interfaces can make it very difficult to know exactly what is the real object that is being passed in to a class, the truth is, as the class under test – do you really care? The answer is No not really. Remind yourself what Interfaces are intended for. They are, in effect, contracts between two (or more) instances. They are an agreement between the parties that x will provide y with data or an action upon data.

If you think of your OO design through the use of Interfaces rather than concrete instantiation of types from directly within your component classes, then you are on your way to using the DI pattern.

Update (April-07-2009): I had previously quoted an article from Wikipedia, which in hindsite was not how I wanted to present DI. Although the article provides a definition of DI, it does so by basing it on Inversion of Control (to achieve Inversion of Control you need to use Dependency Injection). As Martin Fowler states in his article on Inversion of Control, IoC is the container or framework that is made possible by DI. I will cover IoC and it’s practical uses ata later date, but for now I want to concentrate on DI.

By defining the interaction between your classes in terms of interfaces rather than through the use of strongly typed classes then you are immediately starting to de-couple those classes. The idea is simple. By removing the dependency on a concrete Class and shifting it to an Interface, you are in effect, facilitating the implementation of true unit tests.

Thinking about the unit tests you have written previously, I am sure that the majority of us will agree that it has always been necessary to include the use of another class, another instance to actually be able to perform tests on the unit in question. Go on, you’re amongst friends, no-one will laugh. Whisper it out loud if you want to. We could ask ourselves the following questions to see if what we have written are real honest to goodness unit tests or just very light weight integration tests:

  • Does the unit require an instance of any other complex class in order to be able to test it? (By complex class I am referring to a class that will cause the code path from your unit test to perform an type CRUD operation on the data received from/petitioned by your component)
  • If it is included in a build system, does the build system have to have any special configuration / installation to be able to run the unit test?
  • Does there need to be connectivity to a database/network prepared for the unit test to run?


I am sure as time goes by I will add more to this list, but for now you get the general idea. If you have answered yes to any of those questions, then it is NOT a unit test. What we have here then, is integration testing. The code path has not been contained within the unit and therefore we have inadvertently involved one or more classes. The results of the test are then questionable as they do not reflect the actions performed solely within the unit under test.

In the next article I would like to take an example of a legacy laden class and show how we can apply some DI principles to it so that we prepare it for true unit testing.

  • Share/Bookmark