Unit Tests and Static Methods

I am trying to add unit tests to some previously untested code. Said code depends on these utility classes that consist entirely of static methods. These methods do things like talk to the database, get configuration settings, etc. The architecture is really much more procedural than object oriented. I am using NUnit and NMock.

The particular class I am working on depends on six or seven of these utility classes. Since I want to isolate my test, I am trying to create a mock utility class. My problem is that I don’t know the best way to do this. My options are:

  1. Add a non-static method to the utility for each method I need. Then make an interface that matches and a mock oject.
  2. Create an interface with the methods I need and create a wrapper class that implements this interface and calls the static methods.

I don’t like option 1 because I have to think up a new name for the same method and it clutters up the utility for the rest of the application. Option 2 has some issues with it too. Do I make an interface for each utility class I need or one interface with just the functions the class to be tested needs? Where does the class get a reference to the interface? I could pass it in to the constructor, but passing 6 or 7 arguments really bulks up the code. I tried to make a registry class that would hold a reference to each wrapper, but that also grew unweildy.

I’m starting to think that I need a single interface that only this class will use. There will be the interface, a simple implementation that calls the static methods, and a constructor that takes an instance of the interface. This lets me test the class with the least impact on the rest of the system. The only thing that bugs me is that the interface is only used by this one class. On the next class I will have to create another interface.

Option 1 looks like this:

interface IFooUtil
{
	void DoSomethingWrapper();
}

class FooUtility: IFooUtil
{
	public static void DoSomething()
	{}
	public void DoSomethingWrapper()
	{
		DoSomething();
	}
}

interface IBarUtil
{
	public int GetSomethingWrapper()
}

class BarUtility: IBarUtil
{
	public int GetSomething()
	{}
	public int GetSomethingWrapper()
	{
		return GetSomething();
	}
}

Option 2 looks like:

interface IFooUtil
{
	void DoSomethingWrapper();
}

class FooUtility
{
	public static void DoSomething()
	{}
}

class FooHelper : IFooUtil
{
	public void DoSomethingWrapper()
	{
		FooUtility.DoSomething();
	}
}

interface IBarUtil
{
	public int GetSomethingWrapper()
}

class BarUtility
{
	public int GetSomething()
	{}
}

class BarHelper : IBarUtil
{
	public int GetSomethingWrapper()
	{
		return BarUtility.GetSomething();
	}
}

or

class FooUtility
{
	public static void DoSomething()
	{}
}

class BarUtility
{
	public int GetSomething()
	{}
}

interface IClassUtils
{
	void DoSomethingWrapper();
	int GetSomethingWrapper()
}

class ClassUtilWrapper : IFooUtil
{
	public void DoSomethingWrapper()
	{
		FooUtility.DoSomething();
	}
	public int GetSomethingWrapper()
	{
		return BarUtility.GetSomething();
	}
}
Posted in Software Development and tagged . Permalink.

3 Responses to Unit Tests and Static Methods

  1. I really like the second option.
    Combine this with an IoC container like Castle’s or Spring, and you are getting things done very quickly.

    I can recommend the castle’s IoC, no configuration needed in most cases, it’s inferred where ever that is possible.

    http://www.castleproject.org/index.php/Container

    Your second option appear in Working Effectively With Legacy Code, btw. I think that this is the best way to go.

  2. Hey, thanks! I’ll go check both of those out. I haven’t actually used IoC yet so this might be a good chance.

    I’m trying to avoid making changes that are too drastic. I am not the main developer and I’m trying to start out with a few simple tests to see if I can get the others interested.

  3. Pingback: Dave’s Fantasmic Blog » IoC and Testability

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>