2

这必须是微不足道的,但是对于 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<Module> 隐式转换为 System.Collections.Generic.IEnumerable<IModule>

这与这个问题相同。

现在,一定有一些琐碎的事情让我无法理解。据我所知,LoadModules()退货IEnumerable<IModule>是一件好事™。将返回类型更改IEnumerable<Module>为当然会使代码编译,但它只会将问题转移到单元测试。

我有点困惑,也许我做错了(如果是这种情况,我很抱歉)。

那么,你会怎么做呢?我如何制作可Module模拟的?

4

1 回答 1

2

您应该替换varIEnumerable<IModule>并替换new Module(dll)(IModule) (new Module(dll))

于 2012-04-27T19:19:20.553 回答