views:

315

answers:

6

Scenario. Language C#, Unit testing using VS2008 Unit testing framework

I have a static class with a static constructor and 2 methods. I have 4 test methods written to test the entire class. My Static Constructor has some important initializations.

Now if I run all the 4 unit test cases in tandem, the static constructor will be called only at the beginning. At the end of each test case, there is no such thing

called static destructor, So the state info in the constructor gets carried to the next unit test case also. What is the workaround for this.

A: 

Well, you didn't specify which language you were using, but if there is a way to open up your static class from within the test file, then I would add a fake destructor to it, which you can call after each test. That way, the 'destructor' stays in the test class, and out of your production code.

cloudhead
+2  A: 

The simplest solution is to add a "Reset" method to your static class, which would have the equivalent behaviour of destructing it and reconstructing it.

There may be a valid reason why you are using a static class here. However, because statics don't play nicely with unit tests, I usually search for an alternative design.

Andrew Shepherd
A: 

You could use Typemock's Isolator which is capable of mocking static classes, so in each test you can "define" how the static will be operating.

It's not a free product though.

Slace
A: 

It sounds like you're trying to test the static constructor. This seems like a bad idea.

Consider extracting the initialization logic into a separate (non-static) class instead.

For the sake of discussion, let's say your static class is called MySingleton, and let's say you create a new class called MyInitializer, with an Execute method. MySingleton's static constructor could instantiate MyInitializer and call Execute, which does all the initialization.

Then your production code could use MySingleton, and ignore MyInitializer. Your tests, on the other hand, could ignore MySingleton, and merrily create a new MyInitializer instance for each test, getting a fresh start each time.

Joe White
A: 

With out knowing the usage of the class commenting on just the usage is of cause a bit tricky but ill give it a go anyways. To me the above sounds like a smell more than a testing problem.

A static class (just as singletons) are basically a collection of global functions/variables which generally is a bad thing in oop. I'd say trying to test the test issue is (eventhough probably the easiest right now) only fixing the symptom but not the problem.

I'd suggest to take a look at the desing a concidere if you really need the static class or if it just seemed like the easiest way to fix a problem at the time

Rune FS
A: 

I would move the initialization from the static constructor to a method that is called by the constructor. By making this method internal, you can then call this method from your tests to reinitialize the class.

public static class MyClass
{
   public static MyClass()
   {
      initialize();
   }

   internal static void initialize()
   {
      // Do initialization (and cleanup if necessary)
   }

   public static void Method1() {}
   public static void Method2() {}
}

In order to call the internal methods you need to use the InternalsVisibleTo attribute, as described in this blog.

You can also make it private, but then you need to use reflection to call it.

But as Andrew Shepherd said, you should also check if a static class is the best design of this class.

BengtBe