单元测试需要系统库的服务

时间:2009-04-20 09:42:07

标签: c# unit-testing tdd

我正在编写一篇我正在编写的“PluginsService”。我需要使用Assembly,AssemblyName,Directory和File的系统库。目前我正在为每个创建包装器接口,所以我可以在测试中模拟它们。但这确实意味着我不得不在服务中注入相当多的包装器。

例如,当测试一个搜索文件夹中某些插件的方法时,我正在做这个

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());

我有两个问题:

  1. 是否有更好的方法来处理TDD的系统库项目?
  2. 是否有太多项目要注入一个班级?

2 个答案:

答案 0 :(得分:1)

我最近做了同样的事情,想出了一个设计,我有自己的Directory对象,其中DirectoryBoundary是目录的链接。 DirectoryBoundary本身并没有直接进行单元测试,但我使用了一些集成测试来覆盖它。

如果你走向这个方向,我想你会发现你的设计变得更加流畅,你的集成点也更容易。让我们面对现实,.NET File IO类不是为可测试性而设计的。所以想出你自己的。你可以模拟新的Directory类,或者做我做过的事情,只做假边界类和你注入的某种形式的创作者。

希望有所帮助。

答案 1 :(得分:0)

Oren在测试中使用类似的东西来处理DateTime:

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

然后在测试中:

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);

它是注射的替代品,但不是线程安全的。 Dealing with time in tests