views:

58

answers:

1

So I have a class that looks like this:

public class MyClassToTest()
{
    MyStaticClass.DoSomethingThatIsBadForUnitTesting();
}

and a static class that looks like this:

public static class MyStaticClass()
{
    public static void DoSomethingThatIsBadForUnitTesting()
    {
        // Hit a database
        // call services
        // write to a file
        // Other things bad for unit testing
    }
}

(Obviously this is a dumbed down example)

So, I know that the second class is doomed when it comes to unit testing, but is there any way to uncouple the MyClassToTest class so that I can test it (WITHOUT instantiating MyStaticClass). Basically, I would want it to ignore this call.

Note: Sadly this is a Compact Framework Project, so tools like Moles and Typemock Isolator cannot be used :(.

+7  A: 

Define an interface that does the same thing as DoSomethingThatIsBadForUnitTesting, for instance:

public interface IAction {
    public void DoSomething();
}

(Obviously, in real code, you'd pick better names.)

Then you can write a simple wrapper for the class for use in production code:

public class Action : IAction {
    public void DoSomething() {
        MyStaticClass.DoSomethingThatIsBadForUnitTesting();
    }
}

In MyClassToTest, you pass in an instance of IAction via its constructor and call the method on that instance instead of the static class. In production code, you pass in the concrete class Action so the code behaves as before. In the unit test, you pass in a mock object that implements IAction, either using a mock framework or rolling your own mock.

Michael Williamson
Oooooooh, good stuff. I give it a try!
Vaccano
+1 Good answer. the OP said "WITHOUT instantiating MyStaticClass" - and the point is you need to instantiate SOMETHING in order to benefit from dynamic method binding here.
Sanjay Manohar
+1, This is the first step toward no longer implementing static calls with side effects or statically-accessed Singletons. The adapter objects can help you get existing code with static dependencies under test. Ultimately, aim toward pulling out the problematic static calls entirely.
Dan Bryant