Archive for the ‘Unit testing’ Category
Detangling Service Locator From Dependency Injection
I’m sure like many exploring Dependency Injection (DI) for the first time the biggest problem I had, was how to rid the world of those pesky little new statements. The first application I tried to use DI with in anger was DirLinker. I had no prior knowledge of any of the DI frameworks and started looking at patterns that would help me remove all the new statements. Unfortunately, I hit up on service locator and the rest is a mess history. I ended up with code the looks like the following inside DirLinker:
IFile aFile = ClassFactory.CreateInstance<IFile>(); aFile.SetFile(file);
There is a couple of things that bother me about this. First is the static, I’m not a fan of statics at all, infact, I hate them. Next is the SetFile call, for any meaningful work to be done with this class you need to pass in a filename and it should be a constructor argument. In all fairness the SetFile problem is more to do with the limitations of my roll your own DI framework than anything else.
In spite of my niggling doubts, it worked so I left it alone. Fast forward to last week when I came across a blog post entitled Service Locator is an Anti-Pattern. This confirmed my initial discomfort and highlighted a problem I hadn’t thought of, namely that the class doesn’t advertise its dependencies. Very bad for reuse.
Factories
As the blog post suggests a better way of doing this would have been to use factories so lets go over a couple of examples on how this could be achieved.
Virtual Instance Methods
This is a method I would use when trying to a create a seam in legacy code to inject a dependency for unit testing. To do this you create a virtual method on the class that needs to create the object. In the unit test inherit from the class under test and override the factory method to return your mock or stub. For example:
public class FileConsumer
{
protected virtual IFile GetFile(String filename)
{
return new FileImp(filename);
}
public void DoSomething()
{
IFile fileA = GetFile("test.txt");
IFile fileB = GetFile("test2.txt");
//uses files
}
}
[TestFixture]
public class FileConsumerTests : FileConsumer
{
protected override IFile GetFile(string filename)
{
return new FileMock(filename);
}
[Test]
public void DosomethingTest()
{
//Code to perform test
}
}
This is good because it’s clear to any maintainer what the dependency is and where it is coming from.
Abstraction Factory Pattern
This would loudly and proudly advertise the dependency on the ability to create IFile objects. It works by creating a class with methods solely responsible for creating IFile objects and then taking this as dependency for your class. For example:
public interface IFileFactory
{
IFile CreateFile(String filename);
}
public class FileFactory : IFileFactory
{
public IFile CreateFile(string filename)
{
return new FileImp(filename);
}
}
public class FileConsumer
{
IFileFactory _fileFactory;
public FileConsumer(IFileFactory fileFactory)
{
_fileFactory = fileFactory;
}
public void DoSomething()
{
IFile fileA = _fileFactory.CreateFile("test.txt");
IFile fileB = _fileFactory.CreateFile("test.txt");
//uses files
}
}
This is the pattern recommended by the blog post and it covers all the things I don’t like about Service Locator. But I think we could take advantage of some of C#’s language features and the fact we are creating objects via a container to achieve something similar but with less code.
Delegate Factories
Before I go into this a little disclaimer, this is totally and utterly inspired by Autofac’s wonderful generated delegate factory functionality, you can read more about it here.
OK, honesty out of way lets look at what the container knows and what it does. The DI container knows what Interfaces should map on to what concrete types and it has the ability to resolve constructor arguments for types that it knows about. This is just a generic version of a factory so it makes sense to take advantage of it.
One way would be to use Func<TResult>() (and its friends). If the class being constructed requires a constructor parameter of Func<TResult> where TResult is the required interface, the container could generate an appropriate delegate at runtime and pass it in. For example:
public class FileConsumer
{
Func<IFile> _fileFactory;
public FileConsumer(Func<IFile> fileFactory)
{
_fileFactory = fileFactory;
}
public void DoSomething()
{
IFile fileA = _fileFactory();
IFile fileB = _fileFactory();
//uses fileA
}
}
This would require a slight modification to the container and could be extended by the use of Func<T, Tn, TResult>(T value, Tn valuen). The container would match the parameters to a suitable constructor.
This is quite a powerful and time saving concept but I don’t like the vagueness of Func<TResult>(), it’s not as expressive as it could be. So the method I have chosen for DirLinker is to use strongly typed delegates and generate them at runtime from the container. It works in the same manner only you declare the delegate up front and pass them in as an argument. This, also, requires a bit of configuration but the pay off is worth it. I have started work on the implementation for DirLinker so this example is taken directly from the unit tests and can be found here.
interface ITestClassWithDelegateFactory { ITestClassFactory Factory { get; set; } }
delegate ITestClass ITestClassFactory();
class TestClassWithDelegateFactory : ITestClassWithDelegateFactory
{
public ITestClassFactory Factory { get; set; }
public TestClassWithDelegateFactory(ITestClassFactory delegateFactory)
{
Factory = delegateFactory;
}
}
[Test]
public void ManufactureType_Type_delegate_factory_manufactures_correct_type()
{
IClassFactory testClassFactory = new ClassFactory();
testClassFactory.RegisterType<ITestClass, TestClass>()
.WithFactory<ITestClassFactory>();
testClassFactory.RegisterType<ITestClassWithDelegateFactory, TestClassWithDelegateFactory>();
ITestClassWithDelegateFactory manufacturedType =
testClassFactory.ManufactureType<ITestClassWithDelegateFactory>();
ITestClass instance = manufacturedType.Factory();
Assert.IsInstanceOf(typeof(TestClass), instance);
}
Admittedly there is quite a lot going on here but the main points are we registered a type and factory in a strongly typed manner with the container. Then pull it out and use it to create an instance of a different type. I am going to cover this in quite some detail along with the how to create strongly typed delegates at runtime in my next post.
Don’t Be a Fool, Wrap Your Tool!
As a hormone ravaged teenage, I squirmed uncomfortably as parents, teachers and community health practitioners imparted the words of wisdom “Don’t be a fool, wrap your tool”. So it is fitting, I’m equally as squeamish when coming across the same advice as an adult.
What am I talking about? Creating wrappers for anything at all on the boundaries of your code for the purpose of unit testing. I’ve been struggling to think of a succinct way to explain this so I decided to go through a worked example.
Consider the following code:
public class CommandReceiver
{
public void WaitForMessage()
{
using (NamedPipeServerStream pipeServer = new NamedPipeServerStream("testpipe", PipeDirection.In))
{
// Wait for a client to connect
Trace.Write("Waiting for client connection...");
pipeServer.WaitForConnection();
Trace.WriteLine("Client connected.");
try
{
// Read user input and send that to the client process.
using (StreamReader sr = new StreamReader(pipeServer))
{
String command = sr.ReadLine();
DispatchCommand(command);
}
}
catch (IOException e)
{
Trace.WriteLine("ERROR: {0}", e.Message);
}
}
}
private void DispatchCommand(String command)
{
//Knows how to deal with messages.
}
}
Looking at this code there is a number of problems but lets focus on the unit testing problems. It is impossible to unit test this code because it creates a real pipe server and waits on a blocking call before continuing. This means to test this code we need to create a pipe client, connect and all this would have to be threaded because of the blocking call. Of course, this would make a good integration test because it tests that the pipe is connectable and receives a string message.
Before we set about making this code more unit test friendly, lets look at what we are trying to unit test. We are trying to test that the WaitForMessage method can receive a string and pass it on. For us to do this we need to abstract the pipe and stream out. Also, while we are there lets remove the DispatchCommand method since it violates SRP and it would be more testable on its own. So lets take a second stab at the code.
public interface INamedPipeServer : IDisposable
{
void WaitForConnection();
}
public class ManagedNamedPipeServer : INamedPipeServer
{
private NamedPipeServerStream _pipeServer;
public ManagedNamedPipeServer(String name, PipeDirection pipeDir)
{
_pipeServer = new NamedPipeServerStream(name, pipeDir);
}
public void WaitForConnection()
{
_pipeServer.WaitForConnection();
}
public void Dispose()
{
_pipeServer.Dispose();
}
}
public interface IStreamReader: IDisposable
{
String ReadLine();
}
public class ManagedStreamReader : StreamReader, IStreamReader
{
public ManagedStreamReader(Stream stream) : base(stream)
{}
}
public class CommandReceiver : ICommandReceiver
{
INamedPipeServer _NamedPipeServer;
ICommandDispatcher _CommandDispatcher;
public CommandReceiver(INamedPipeServer pipeServer, ICommandDispatcher dispatch)
{
_NamedPipeServer = pipeServer;
_CommandDispatcher = dispatch;
}
protected virtual IStreamReader GetStreamReader()
{
//Code to create a stream reader from the pipe
}
public void WaitForMessage()
{
// Wait for a client to connect
Trace.Write("Waiting for client connection...");
_NamedPipeServer.WaitForConnection();
Trace.WriteLine("Client connected.");
try
{
// Read user input and send that to the client process.
using (var sr = GetStreamReader())
{
String command = sr.ReadLine();
_CommandDispatcher.DispatchCommand(command);
}
}
catch (IOException e)
{
Trace.WriteLine("ERROR: {0}", e.Message);
}
}
}
This is where my uncomfortable squirm returns because my “keep-it-simple” sense is tingling. I’ve just taken a fairly simple class that was around 30 lines and turned it into 75 lines of complicated OOP code. I would hope that anyone reading this can follow it but in a real project this will probably be split over several files and the two styles of wrapping (because NamedPipeServerStream is sealed) can add significant cognitive burden to understanding what is going on.
What benefits does this bring? It allows us to unit test that we read a string and pass it on to a dispatcher. But I would go out on a limb and say that this is least likely of all the code in that class to go wrong. The real problem area will be in connecting the pipe and reading from it. We can make assumptions about failure conditions from the docs but as we all know docs != reality.
Is the abstraction here a benefit? In my opinion, not to the extreme level we have. The abstraction at ICommandReceiver will allow us to swap out how the application does IPC calls making it flexible in the future and, as I eluded to above, the unit test ‘coverageability’ is of lower value in this instance.
My point in all this rambling nonsense? In an ideal world we would have both sets of tests and the unit tests would cover all the error conditions but in the real world we only have a finite and, usually, short amount of time with pressure from project managers and deadlines. So we have to look at what will bring us the most value and focus on that. I believe at application boundaries like this one we should focus our attention on writing integration tests because it will bring us more value in the long run. I would not shun unit testing entirely and in this example the ICommandDisptacher and other supporting classes would have a full suite of unit tests.
As a side note, my final version of the code would be a mid way point between the two listings.
Why Unit Testing is Essential When Learning a New Language
I’ve been spending a bit of time lately learning Python and Pythonista ways, although a lot of the stuff I’ve read is more about the how of dynamic languages not the why but that’s another discussion. I find the best way to learn a new language is to pick a pet project and run with it. As random as it may seem this fits in nicely with my new years resolution of losing weight. So I started a Diet Tracker website using the Django framework.
In my continuing quest to use and learn more about Test Driven Development one of the first things I spent time diving into (after the basic syntax) was the built-in unit test framework in Django, the Python standard library has one too but the Django one is richer. It paid off quite quickly.
One of the key parts of the site was the ability to track your changing weight. The first version of the weight display page is sortable in ascending or descending order and can have a selectable number of entries. Also, weights will be stored in the model as KG but displayed in stone and pounds, this will be made user configurable at a later date. The exceedingly simple algorithm for this page is:
- Accept a list of weights
- Reverse the sort order if we need it to be newest first
- Take X number of items
- Create a new list of the display adapter class
I would write this in C# as something like:
public List<DisplayWeight> ConvertToDisplayWeightList(List<ModelWeight> weights, int numberForDisplay, bool newestFirst)
{
if (newestFirst)
{
weights.Reverse();
}
List<DisplayWeight> returnList = new List<DisplayWeight>();
weights.GetRange(0, numberForDisplay).ForEach( mw => returnList.Add(new DisplayWeight(mw)));
return returnList;
}
This does look WTF-esq but it’s not that bad once you understand how Django’s ORM works. The Python I wrote to do this was:
def get_display_weight_list_by_date(self, numberToLoad = 5, newest_first = True):
currentWeightList = Weight.objects.all().order_by('date')
if newest_first:
currentWeightList.reverse()
finalList =[]
for w in self.currentWeightList[:numberToLoad]:
finalList.append(DisplayWeight(w))
return finalList
def testLoadWeights_5items_newest_first(self):
"Checks we have 5 weights returned and the newest is first"
loader = DisplayWeightLoader()
loader.get_display_weight_list_by_date(numberToLoad=5, newest_first=True)
self.assertEquals(len(loader.currentWeightList), 5)
self.assertEquals(loader.currentWeightList[0].date, datetime.date(2010, 01, 19))
def testLoadWeights_10items_oldest_first(self):
"Checks we have 10 weights returned and the last is first"
loader = DisplayWeightLoader()
loader.get_display_weight_list_by_date(numberToLoad=10, newest_first=False)
self.assertEquals(len(loader.currentWeightList), 10)
self.assertEquals(loader.currentWeightList[0].date, datetime.date(2010, 01, 9))
The function is not very pythonic and a bit WTFy, I’ve rewritten it since, but the second unit test failed. Without going into where the test data is coming from or what is going on, the test is failing because the newest date is still first. Why is it failing? Because I made an assumption.
The assumption? That an instance method on an instance of a mutable object affects the state of that object. I think it’s a fair assumption and it is the way that C# works. But it turns out not to be the case in Python, the line at fault:
currentWeightList.reverse()
It should be
currentWeightList = currentWeightList.reverse()
There is a couple of very important lessons here:
- Never make assumptions: Yet more proof that assumptions make an ass out of you and me.
- Reading language and library documentation is extremely important: I had skimmed over the tutorials and docs for the standard Python library and I thought I knew enough to get up and running. I should really have gone back and read the documentation properly for the functions I’m using for the first time.
The most important lesson though:
Unit testing is not an advanced skill or topic, it is essential and part of the basics
Unit testing is not part of the standard Python docs tutorial, it is at the end of the Django tutorial (to be fair it is mentioned briefly early on) and barely gets a mention on MSDN. Implying that it’s not that important and it’s something you can leave to later. I think that it is extremely important, whether you’re an experienced developer trying to get to grips with a new language or a beginner trying to get to grips with programming it is the single most important thing after learning the syntax.
At every level it helps you to think about what you’re actually trying to achieve, gives you instance feedback to your understanding of a feature, language or library and helps you to write small simple functions.