How to including static services in a testable way

0  comments

There are often times when you want to include static services in your code. For example, when accessing the file system or including an external analytics package. When you do, it presents a testability problem. Every time you exercise the code via a test, that static service is also called. This post explains a simple pattern I use to solve this issue.

The problem code

https://gist.github.com/codescribler/fa7f4e3b87f1973382c0 The issue here is that every time a test runs this code it must interact with the file system to ensure it is in the state expected for the test. At best this is going to be slow but at worst can yield incorrect results. What if the someone is already creating files in that folder or it becomes unavailable or the account running the test does not have the required permissions (this list of possible issues goes on and on). The most valuable tests you can write here are ones to ensure the logic is executes as expected, in this case to throw an exception if the file already exists or to write the data to the file if it does not. You could of course go to town and check the parameters and catch various exceptions but for this post I'll ignore those possibilities.

The wrapper object

Step 1 - Define the interface

A simple approach to solving this problem is to use a wrapper object. Start off by identifying the 'services' you need from the static class. In this case you will need a 'FileExists' method that returns a bool and a WriteAllText which is a void. Clearly the static class has many more methods but you should only implement the ones you actually use. This way you minimise the code any implementer of your interface must write. This should lead you to an interface that looks something like this: https://gist.github.com/codescribler/0a46a453e1d5990f0929

Step 2 - Implement the concrete class

The implementation of the actual class is then very simple. Just pass the call down to the original static class methods. https://gist.github.com/codescribler/2b4be15884a42e7913c0

Step 3 - Inject your new service into the original class

The final step is to simply adjust the original class to use your interface rather than the static class directly. This gives you the option of swapping out the actual implementation so that in production the code uses the wrapped class while during test you can inject a fake. https://gist.github.com/codescribler/cfaeaf94b086c2112dad By programming against your new interface you have removed the direct dependency on the static class and made your class easy to test.

Tags

c#, tdd


You may also like

CQRS + Event Sourcing – Step by Step

A common issue I see is understanding the flow of commands, events and queries within a typical CQRS Event Sourcing based system. The following post is designed to clear up what happens at each step. Hopefully, this will help you to reason about your code and what each part does. What is CQRS and what

Read More

Are You Making These 10 DDD Mistakes?

Making mistakes is part of programming. Spotting them early can save you time. I’ve started to notice a common set of ‘DDD Mistakes’ which many of us seem to make. And yes, I’ve made them all at some point in my career. This is by no means the definitive list – I’m sure there are

Read More