如何在 .NET 3.5 中正确模拟
本文关键字:模拟 NET | 更新日期: 2023-09-27 18:32:43
这肯定是微不足道的,但是对于TDD来说,我很难找到正确的方法。
假设我们有一个 WinForms 应用程序,作为其启动过程的一部分,在给定文件夹中查找 DLL 以动态填充其主菜单栏。
这些 DLL 只是插件:它们都实现一个接口,并且它们都将显示为菜单项。就这么简单。
让我们将每个 DLL 称为 Module
。
现在,我想"嘿,史蒂夫,你将不得不嘲笑这个Module
对象。让我们定义一个名为 IModule
的接口,并使 Module
类实现它。这样你就可以随心所欲地嘲笑他们"。
所以,让我写几行代码,特别是IModule
和Module
(我在没有编译器支持的情况下直接编写,所以它可能无法编译(:
<!-- 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
可模拟?
您应该将
var
替换为IEnumerable<IModule>
并将new Module(dll)
替换为(IModule) (new Module(dll))