views:

100

answers:

6

Hi,

I have the following method for which I am trying to write a unit test:

using StaticClass;           // writen by some one else, have a dll

namespace Test
{
  Class TestClass
   {
      public void DoSomething(string param1)
      {
         List<string> = StaticClass.GetList(param1)

         // sort the list and do other studd here
      }
  }
}

When I am not sure how to write a test for the DoSomething method, that depends on a static method in another class. The output of that method depends on things like the database on that machine, the environment and few other other factors. So if databases on two machines are different, the same method would give different results. All I know is that GetList returns some value and that method may or maynot have been unit tested by the creator of that class.

How can I test such a method? Is it possible to say something like, whenever StaticClass.Getlist method is called return a custom List<String> that i created in my program? I am writing tests on c#.

Thanks,

A: 

You'll need to use Mock objects to test this kind of thing. See this great article: http://gamesfromwithin.com/mock-objects-friends-or-foes

Basically you'll make an object that emulates the objects it interfaces with and then verify your expectations.

infamouse
A: 

If I see this right this method will not compile. But if you like to test the method in the static class this could be tested seperatly.

The method in your class does not return anything. If in a system there are only inputs you dont need to implement it.

schoetbi
A: 

You can create a non-static wrapper for the static class, and use the wrapper instead.

something like

Class StaticClassWrapper {
  public List<string> GetList(string param1) {
    return StaticClass.GetList(param1);
  }
}

and then you use the wrapper instead of the static class in your TestClass

Samuel Carrijo
A: 

Make StaticClass a dependancy that you can mock with Moq, Rhino etc. You are then free to either mock out StaticClass to return a known List<string> or simply verify it gets called through the mock.

Daz Lewis
+4  A: 

Static types with methods that have side-effects are troublesome.

You have two options:

  • Short Term: Write an interface which has a GetList method with the right signature. Next write an adapter - a class that implements this interface and delegates to StaticClass internally. Pass an instance of this adapter type into your class as a ctor arg or a method arg. Call GetList on it. You can now use a mocking framework to create a mock object and pass it in your tests and set it up to return canned values.
  • Long term: Convert the StaticClass into a non-static one. Pass it in (instead of the adapter object) ; but this requires source code access to StaticClass.
Gishu
Well put. Remember, OP, you are trying to test your method, not `StaticClass.GetList()`. Your method depends on `GetList()`'s signature (takes a string, returns a `List<string>`) (think interface), not on a particular implementation of that signature (StaticClass.GetList()).
Sam Pearson
+1  A: 

This is one of the reasons that using statics in this way is sometimes frowned upon -- handy though they are, they are very difficult to test.

One approach is to abstract the work of that class into something else.

For example, you could declare

public interface ISomeonesDllService 
{
    IList<string> GetList(string param1);
}

Now create an implementation that uses StaticClass:

public class SomeonesDllService : ISomeonesDllService
{
    public IList<string> GetList(string param1)
    {
        return StaticClass.GetList(param1);
    }
}

To make TestClass testable, you can inject the dependency on this external service in the class constructor:

public class TestClass
{
    ISomeonesDllService dllService;

    public TestClass(ISomeonesDllService dllService)
    {
        this.dllService = dllService;
    }

    public void DoSomething(string param1)
    {
        IList<string> strings = dllService.GetList(param1);
        // do work
    }
}

Now you can very easily test the DoSomething() method because in your test fixture you can instantiate TestClass using a different implementation of ISomeonesDllService. You can hand-roll a stub that just returns a static list of strings, or you can use a mocking framework, like Rhino.Mocks to do set this up for you (which I recommend).

This way you can isolate DoSomething() from the workings of external dependencies.

Jay