views:

61

answers:

2

I'm currently tdding a "PluginsService" that I'm writing. I'm needing to use the System libraries of Assembly, AssemblyName, Directory and File. Currently I'm creating wrapper interfaces for each of these so I can mock them in the tests. This does mean however that I'm having to inject quite a few wrappers into the service.

So for example when testing a method that searches a folder for some plugins I'm doing this

With.Mocks(mockery)
    .Expecting(() =>
    {
            Expect.Call(directory.GetFiles(PLUGINPATH, PLUGINSEARCHPATTERN)).IgnoreArguments().Return(pluginLibraries);
         Expect.Call(file.ReadAllBytes(null)).IgnoreArguments().Return(bytes);
               Expect.Call(assemblyName.GetAssemblyName("fileName")).IgnoreArguments().Return(name);
         Expect.Call(assembly.GetExecutingAssembly()).Return(executingAssembly);
    })
 .Verify(() => result = service.FindAvailablePlugins());

I have 2 questions:

  1. Is there a better way of handling System library items for TDD?
  2. Is 4 too many items to be injecting into one class?
+1  A: 

I did this same thing recently and came up with a design where I had my own Directory object which had a DirectoryBoundary that was the link to the directory. The DirectoryBoundary itself was not directly unit tested, but I used some integration tests to cover it.

If you go in this direction, I think you'll find that your design becomes much more fluent and your integration points are easier. Let's face it, the .NET File IO classes weren't designed for testability. So come up with your own. You can mock the new Directory classes, or do what I did and have just fake Boundary classes and some form of a creator that you inject in.

Hope that helps.

Michael Hedgpeth
A: 

Oren used something like this to deal with DateTime in tests:

public static class SystemTime
{
  public static Func<DateTime> Now = () => DateTime.Now;
}

and then in tests:

SystemTime.Now = () => new DateTime(2000,1,1);
repository.ResetFailures(failedMsgs); 
SystemTime.Now = () => new DateTime(2000,1,2);
var msgs = repository.GetAllReadyMessages(); 
Assert.AreEqual(2, msgs.Length);

It's an alternative to injection but not thread safe. Dealing with time in tests

Petar Repac
thanks I'll have a look at this
John Polling