1

In my asp.net application, I have the below static class to handle query strings in my app to which some classes have dependency:

public static class QueryStringUtil
{
    public static int? GetStoreId()
    {
        return GetId(QueryStrings.StoreId);
    }

    public static string GetItemCode()
    {
        return Get(QueryStrings.ItemCode);
    }       

    private static string Get(string queryStringName)
    {
        return HttpContext.Current.Request.QueryString[queryStringName];
    }

    private static int? GetId(string queryStringName)
    {
        var queryString = Get(queryStringName);
        int queryStringParsed;
        return int.TryParse(queryString, out queryStringParsed) ? (int?)queryStringParsed : null;
    }
}

What would be the best way to make this class testable?

One way that I know would be to refactor this and create a singleton instance class instead with its interface and enabling the dependent classes to accept an interface of my singleton class. Not sure it would be my best option.

Another option would be to make my class a normal class with interface and then creating a singleton ServiceLocator class responsible to hold instances to all classes that should behave like a singleton, such as my QueryStringUtil, then allowing my dependent class to accept interface to my IQueryStringUtil.

Third option I can think of is not using my Custom Service Locator class instead using an IoC container, such as Microsoft Unity, then holding a singleton instance in the IoC container config file and injecting that to my dependent classes.

Please advise your best option and why.

Many thanks,

The Light
  • 26,341
  • 62
  • 176
  • 258

3 Answers3

2

I really like the last option with the IoC container. This is its power - it is responsible for the lifecycle and dependencies of your objects.

Petar Minchev
  • 46,889
  • 11
  • 103
  • 119
0

I prefer interface and normal class in IoC container. You can create instances and control values sended to your tested classes/methods with any mocking framework. Otherwise you will be forced use some isolation framework like TypeMock or Moles to simulate values from your static methods.

Petr Klíma
  • 146
  • 3
0

I know I'm off the point, but I think you're not talking about making this class testable, but about making other classes that depend on it testable.

When you are testing these classes, maybe having an interface for QueryStringUtil might be useful ... ?

However, to try a more general answer, any type of singleton is a testing liability (it is a form of global state, just like global variable, file or database). The general answer to this problem is to use Injection of Dependencies (I think that name is more precise and understandable than "Inversion of Control", that actually means several different things according to different people). I'm not familiar with Asp.net, so I can't tell you which library to use, but you will have no problem finding one.

Dependency injection will make use of a Singleton, but not in your code so you can test your code as if it wasn't a Singleton.

KLE
  • 23,689
  • 4
  • 56
  • 62