使用Moq模拟内部类以进行单元测试

时间:2013-07-10 11:41:45

标签: unit-testing mocking moq

假设我有一个班级" ClassA",它依赖于班级" ClassB" (注入ClassA的构造函数)。我想模拟ClassB,以便我可以单独测试ClassA。这两个课程都是内部的。

如果我错了,请纠正我,但看起来Moq只能模拟一个类,如果它是公共的,它有一个公共无参数构造函数,并且要模拟的方法是public virtual。我真的不想让这些课程公开可见。我错过了Moq的东西,还是不适合我想做的事情?

我想我可以创建一个ClassB实现的接口(比如" IClassB"),将其注入ClassA,然后模拟接口。 ClassB仍然可以是内部的(虽然我意识到接口方法必须是公共的)。虽然这可行,但我对创建大量接口感到不安,其唯一目的是支持单元测试模拟。想法?

2 个答案:

答案 0 :(得分:55)

您可以通过在项目的 assembly.cs 中添加InternalsVisibleToAttribute来向Moq显示内部结构,如下所示:

[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]

为什么"DynamicProxyGenAssembly2"而不是"Moq"?它是动态程序集的名称,用于包含动态生成的代理类型(所有这些都由另一个库处理, Castle的DynamicProxy )由Moq使用。因此,您将类型公开给动态代理程序集,而不是Moq本身。

但是,如果没有可覆盖的成员,那么嘲笑课程有什么意义呢?您不会模拟任何内容,所有调用都将使用实际实现。你的第二个解决方案,

  

我想我可以创建一个ClassB实现的接口(比如“IClassB”),将其注入ClassA,然后模拟接口。

是我通常会做的。它的目的不仅仅是“支持单元测试模拟” - 它可以帮助你构建丢失耦合的组件,这总是值得瞄准的。

答案 1 :(得分:1)

此外,您可以将其添加到 .csporj 文件中。

<ItemGroup>
  <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
  <_Parameter1>DynamicProxyGenAssembly2</_Parameter1>
  </AssemblyAttribute>
</ItemGroup>