使用NUnit进行MEF和单元测试

Dav*_*ave 4 unit-testing mef system.componentmodel

几个星期前,我跳过了MEF(ComponentModel)的潮流,现在我正在使用它来插入很多插件和共享库.总的来说,除了我经常犯的错误之外,它一直很棒,这导致令人沮丧的调试会话.

无论如何,我的应用程序运行良好,但我的MEF相关代码更改导致我的自动构建失败.我的大多数单元测试都失败了,因为我测试的模块依赖于需要由MEF加载的其他模块.我通过绕过MEF并直接实例化这些对象来解决这些问题.

换句话说,通过MEF,我会有类似的东西

[Import]
public ICandyInterface ci { get; set; }
Run Code Online (Sandbox Code Playgroud)

[Export(typeof(ICandyInterface))]
public class MyCandy : ICandyInterface
{
    [ImportingConstructor]
    public MyCandy( [Import("name_param")] string name) {}
    ...
}
Run Code Online (Sandbox Code Playgroud)

但在我的单元测试中,我会使用

CandyInterface MyCandy = new CandyInterface( "Godiva");
Run Code Online (Sandbox Code Playgroud)

另外,CandyInterface需要连接到数据库,我通过将测试数据库添加到我的单元测试文件夹来解决这个问题,我让NUnit使用它来进行所有测试.

好的,以下是我对这种情况的疑问:

  1. 这是一种做坏事的坏方法吗?
  2. 你会建议在[SetUp]中编写部件吗?
  3. 我还没有学会如何在单元测试中使用模拟 - 这是一个很好的例子,我可能想要模拟底层数据库连接(不知何故)只返回虚拟数据而不是真正需要数据库?
  4. 如果您之前遇到过这样的事情,您能否提供您的经验和解决问题的方式?(或者这应该进入社区维基?)

Mar*_*ann 10

听起来你走在正确的轨道上.单元测试应该测试一个单元,这就是你直接创建实例时所做的.如果你让MEF为你编写实例,他们会倾向于集成测试.并非集成测试有任何问题,但单元测试往往更易于维护,因为您可以单独测试每个单元.

在单元测试中,您不需要容器来连接实例.

我通常建议不要在SetUp中组合Fixtures,因为它会导致General Fixture反模式.

最好用Test Doubles替换依赖项.动态模拟是这种方式的多种方式之一,所以你应该学习一些东西.