【问题标题】:How to properly mock in .NET 3.5如何在 .NET 3.5 中正确模拟
【发布时间】:2012-05-08 12:58:51
【问题描述】:

这必须是微不足道的,但是对于 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

this问题相同。

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

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

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

【问题讨论】:

    标签: c# .net-3.5 mocking covariance contravariance


    【解决方案1】:

    您应该将var 替换为IEnumerable&lt;IModule&gt;,并将new Module(dll) 替换为(IModule) (new Module(dll))

    【讨论】:

    • 所以……就是这样,对吧?一个简单的演员阵容。我真的需要一个假期。谢谢你,@DevinB。我必须将实现某个接口的类的实例转换为同一个接口的确切原因对我来说仍然有些不清楚,我想我真的必须阅读 Eric Lippert 关于方差的帖子。顺便说一句,替换var 并不是真正需要的,如果确实需要,我会感到非常惊讶。再次感谢。
    • 我知道替换 var 并不是真正需要的,但最好明确一点,尤其是在这种情况下,整个问题是 LINQ 查询返回了意外的类型。在这种情况下,清晰是迄今为止发现和消除错误的最重要因素。
    • 公平点,DevinB。非常感谢。现在我可以嘲笑了:)
    猜你喜欢
    • 2011-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-17
    • 2021-08-30
    • 2019-10-09
    • 1970-01-01
    • 2018-07-02
    相关资源
    最近更新 更多