Question

Sometimes, especially when working with third party code, I write unit-test specific code in my production code. This happens when third party code uses singletons, relies on constants, accesses the file-system/a resource I don't want to access in a test situation, or overuses inheritance. The form my unit-test specific code takes is usually the following:

if (accessing or importing a certain resource fails)
    I assume this is a test case and load a mock object

Is this poor form, and if it is, what is normally done when writing tests for code that uses untestable third party code?

Was it helpful?

Solution

I normally add a layer of abstraction for a third party component.

Say I have a static class called User:

public static class User
{
   public static void Login(string username, string password)
   {
      // Logic
   }
}

Imagine that User is a third party component for authentication.

I would then create an interface that would represent behaviour of my static class:

public interface IUser
{
   void Login(string username, string password);
}

I would then create a default implementation that would talk to the static class:

public class UserDefault: IUser
{
   public void Login(string username, string password)
   {       
       User.Login(username, password);
   }
}

User is a third party component and I don't need to unit test its logic. What I might want to do in my unit test is verify that I've called User.Login("admin","Foo") only once.

In my unit test I can now create a mock object based on IUser and set expectations on that mock.

OTHER TIPS

Few things before we look into what can be done
-- Testing the code that we author to work as expected is a Must
-- Having test code in production code is IMO a code smell

In reality, the module we author depends on libraries and other components
1> The libraries could be authored by other team within the company
2> The libraries could be authored by 3rd party companies

If the library is authored by 3rd party or other company
Know that the 3rd party is one of the suitable vendors for the library(not the only one)
There may be a better solution provider emerging tomorrow
Hence you must design your dependency such that you can switch between those solutions easily
Hence I would suggest, think about isolating that 3rd party library usage and loosely couple your solution with the 3rd party library
You may do this by introducing a interface to wrap the capabilities of the 3rd party
This will give you a added benefit of making your code testable ie during test you will mock the 3rd party library capability and test various scenarios

If the library is authored by different team within your company
One approach is still isolate the capability of the library by defining interfaces
But i would suggest that this is a FIP (Frog in the pond) approach which would not be beneficial on the long run
In this case i would suggest you to go talk to the other team members and help them see the light
Often when this is not possible the system architects/project leads need to pitch in

Licensed under: CC-BY-SA with attribution
scroll top