Dav*_*son 6 c# methods unit-testing moq abstract
我有一个类A,我正在单元测试一个方法,它将类B作为参数.类B是我想要模拟出来的,它是一个抽象类.该课程类似于以下内容.
public abstract class B
{
internal abstract void DoSomething();
}
Run Code Online (Sandbox Code Playgroud)
我的单元测试看起来像.
[TestMethod]
public void ClassA_Add_TestSomething()
{
var classA = new A();
var mock = new Mock<B>();
classA.Add(mock.Object);
// Assertion
}
Run Code Online (Sandbox Code Playgroud)
我收到以下异常.
测试方法TestSomething引发异常:
System.ArgumentException:类型为mock必须是接口或抽象或非密封类.---> System.TypeLoadException:程序集'DynamicProxyGenAssembly2,Version = 0.0.0.0,Culture = neutral,PublicKeyToken = null'类型'Castle.Proxies.BProxy'中的方法'DoSomething'没有实现.
我可以通过使方法虚拟而不是抽象来解决这个问题,但这不是我想要通过API设计实现的.我也试过提供一个实现mock.Setup(m => m.DoSomething()),但无济于事.这是可能的Moq,还是我将不得不创建一个派生自抽象类B的具体测试类?我想避免创建具体类型,这种类型会破坏使用模拟或存根框架的某些目的,或者我在这里误导?
编辑我发现,如果我制作方法,public abstract则不会发生此问题.所以我想真正的问题是,当使用InternalsVisibleTo和Moq时,使用内部方法是否可行.
Moq依靠Castle Dynamic Proxy来实现其模拟.在运行时,Moq会创建一个新程序集并将其加载到AppDomain中(异常消息中出现名称DynamicProxyGenAssembly2).
问题是此程序集无法访问内部类和您自己的代码的成员,因为它们在您声明它们的程序集之外不可见.
一个解决办法是与标记你的装配InternalsVisibleToAttribute和动态指定生成的程序集的名称:
[InternalsVisibleTo("DynamicProxyGenAssembly2")]
Run Code Online (Sandbox Code Playgroud)
但请记住,此解决方案依赖于实现细节,并可能在将来的版本中停止工作.
internal abstract仔细考虑一下为什么你在公共类上有一个方法。其他人将无法实现抽象方法,因为它对他们不可见。也许这就是你想要的。有时,考虑到各种设计限制,这是一种有效的方法。如果您的库将被其他人使用,我建议至少将构造函数也设置为内部,这样就没有人知道他们可以实现抽象类。
| 归档时间: |
|
| 查看次数: |
3851 次 |
| 最近记录: |