Home > Agile, C#, Dependency Injection, Design Patterns, Development, Mock Objects > Unit Testing Legacy Code with Dependency Injection and Mock Objects – Part I

Unit Testing Legacy Code with Dependency Injection and Mock Objects – Part I

January 21st, 2008 Scott Lilly

Solution file

The team I’m working with has a lot of legacy code with no unit tests. The first demo that I gave was how to add unit tests to this existing code, and how using mock objects with dependency injection can help with code coverage and removing the requirement of external resources. I’ll take a few posts to walk you through one way to do this. While there are some nice mock object libraries out there, I’m use manually created mocks for this demo. When we add in unit tests, it will be with NUnit. Since my client is using Visual Studio Team System, we used the Windows unit test classes. They both operate the same, and the syntax is amazingly similar.

First, a little bit about this demo program. This is a Windows form application written in C#. It simulates a data entry program for address information (street address, city, state, ZIP code). When the user enters in the address information, and clicks the “Save Address” button, the address is validated against a third-party web service, and saved if the address is valid. If the web service returns a “false”, or the program can’t connect to the web service, an error message should be displayed and the address should not be saved to the database.

The project “DI_Demo” is the Windows form application, and the project “BusinessObjects” is where the business logic resides. The DI_Demo project has a reference to the BusinessObjects project, and BusinessObjects has a web reference to the AddressValidationService. For the purposes of this demo, I created the web service on my local machine and it returns a “true” if all the fields are populated, “false” if any of them are empty. In real-life, this might be a company like the post office that provides a web service as a way for an application to verify that an address exists.

Here is the code in its “legacy” state. In the next post, I’ll show how to gradually make changes to it that will make it more testable.

The code for the entry form (AddressEntryScreen.cs) is:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using BusinessObjects;

namespace DI_Demo
{
   public partial class AddressEntryScreen : Form
   {
      public AddressEntryScreen()
      {
         InitializeComponent();
      }

      private void btnSaveAddress_Click( object sender, EventArgs e )
     {
         PropertyAddress addr = new PropertyAddress();

         try
         {
            addr.Save( txtStreetAddress.Text, txtCity.Text, txtStateCode.Text, txtZipCode.Text );
            lblStatusMessage.Text = “‘” + txtStreetAddress.Text + “‘ was saved”;
         }
         catch ( Exception ex )
         {
            lblStatusMessage.Text = ex.Message;
         }

      }
   }
}

The code for the address business object (PropertyAddress.cs) is:

using System;
using System.Collections.Generic;
using System.Text;

using BusinessObjects.AddressValidationService;

namespace BusinessObjects
{
   public class PropertyAddress
   {

      public void Save(string streetAddress, string city, string stateCode, string zipCode)
      {
         ValidationService validator = new ValidationService();
         if(validator.IsAddressValid(streetAddress, city, stateCode, zipCode))
         {
            // Code to save to the database would go here.
         }
         else
         {
            throw new ArgumentException( “Property address is not valid.  Data was not saved.” );
         }
      }
 
   }
}

Comments are closed.