【问题标题】:Unit Testing a service with System libraries required需要使用系统库对服务进行单元测试
【发布时间】:2009-04-20 09:42:06
【问题描述】:

我目前正在编写我正在编写的“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. 一个类中要注入 4 个项目太多了吗?

【问题讨论】:

    标签: c# unit-testing tdd


    【解决方案1】:

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

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

    希望对您有所帮助。

    【讨论】:

      【解决方案2】:

      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

      【讨论】:

        猜你喜欢
        • 2016-12-14
        • 2011-01-15
        • 1970-01-01
        • 2014-05-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-26
        • 2019-01-24
        相关资源
        最近更新 更多