如何在 .NET 3.5 中正确模拟

本文关键字:模拟 NET | 更新日期: 2023-09-27 18:32:43

这肯定是微不足道的,但是对于TDD来说,我很难找到正确的方法。

假设我们有一个 WinForms 应用程序,作为其启动过程的一部分,在给定文件夹中查找 DLL 以动态填充其主菜单栏。

这些 DLL 只是插件:它们都实现一个接口,并且它们都将显示为菜单项。就这么简单。

让我们将每个 DLL 称为 Module

现在,我想"嘿,史蒂夫,你将不得不嘲笑这个Module对象。让我们定义一个名为 IModule 的接口,并使 Module 类实现它。这样你就可以随心所欲地嘲笑他们"。

所以,让我写几行代码,特别是IModuleModule(我在没有编译器支持的情况下直接编写,所以它可能无法编译(:

<!-- language: c# -->
public interface IModule {
    string Id { get; }
    string DisplayName { get; }
}
public class Module : IModule {
    public string Id { get; }
    public string DisplayName { get; }
    public string Path { get; private set; }
    public Module(FileInfo path) {
        Path = path.FullName;
    }
}

而且,当我们这样做时,让我们实现将执行实际加载的类:

public class ModuleLoader {
    IEnumerable<DirectoryInfo> SearchPaths;
    public ModuleLoader(IEnumerable<DirectoryInfo> searchPaths) {
        SearchPaths = searchPaths;
    }
    public IEnumerable<IModule> LoadModules() {
        var modules = SearchPaths
            .Where(dir => dir.Exists)
            .SelectMany(dir => dir.GetFiles("*.dll").Select(dll => new Module(dll)));
        return modules;
    }
}

问题来了:LoadModules()不会编译,因为——据我所知——差异问题。

错误消息如下:

无法将类型System.Collections.Generic.IEnumerable

隐式转换为System.Collections.Generic.IEnumerable

这与这个问题相同。

现在,一定有什么微不足道的事情逃脱了我。据我所知,让LoadModules()回归IEnumerable<IModule>是一件好事™。将返回类型更改为 IEnumerable<Module> 当然会使代码编译,但它只会将问题移动到单元测试中。

我有点困惑,也许我做错了(如果是这样的话,我深表歉意(。

那么,你会怎么做呢?如何使Module可模拟?

如何在 .NET 3.5 中正确模拟

您应该将

var替换为IEnumerable<IModule>并将new Module(dll)替换为(IModule) (new Module(dll))