Search code examples
c#unit-testingmoqlegacy

A simple way to convert a static class to regular class in legacy applications to enable mocking


Static classes in legacy applications are hard to use in unit tests because you cannot mock them.

What is a simple way to convert them across the whole application to regular classes that use an Interafce?


Solution

  • It is easiest and less risky to do this in two steps.

    The first step is repetitive and uncreative and can be assigned to a junior engineer or could even be done with a small program.

    For each class, follow these steps:

    1. Remove the static keyword from the desired methods and properties.

    2. Add a static member called Instance that contains an instance of the class. Yes, we're making a singleton.

       //Old class
       static class MyHelpers
       {
           public static string Foo(string x) {  /* Implementation */ }
       }
      
       //New class
       class MyHelpers
       {
           public static MyHelpers Instance { get; } = new MyHelpers();
           public string Foo(string x) { /* Implementation */ }
       }
      
    3. In the rest of your code base, replace static calls with calls to the instance.

       //Old code
       MyHelpers.Foo("Hello world");
      
       //New code
       MyHelpers.Instance.Foo("Hello world");
      
    4. Compile to make sure you didn't miss any spots

    5. Test & check in source code

    The second step is optional. We really want to get rid of those Instance keywords as they break IoC (and if you keep a singleton in your code base other engineers will make fun of you). This will require you

    1. Add one or more interfaces

    2. Arrange for the class to be injected or otherwise made available everywhere Instance is used.

    3. Search/replace to remove ".Instance" from all the calls.

    The second step requires a little more thinking and should be assigned to a more intermediate engineer. If you have large code base, you can do this over time, or just make the change tactically as you touch code.