模拟从摘要 class 派生的摘要 class
Mocking an abstract class derived from an abstract class
我有两个这样的类
public abstract class Foo<T> where T : Bar {
public Bar Do(Bar obj) {
//I cast to T here and the call the protected one.
}
...
protected abstract Bar Do(T obj);
}
public abstract class FooWithGoo<T> : Foo<T> where T:Bar {
...
}
尝试在单元测试中使用 Moq 对此行进行模拟 new Mock<FooWithGoo<Bar>>()
给了我这个异常。
System.ArgumentException: Type to mock must be an interface or an abstract or non-sealed class. ---> System.TypeLoadException: Method 'Do' in type 'Castle.Proxies.FooWithGoo``1Proxy' from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.
我这里有什么地方做错了吗?我该如何嘲笑它?
更新:
这对我来说很好地说明了问题。
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
namespace UnitTestProject1
{
public class Bar
{
}
public class BarSub : Bar
{
}
public abstract class Foo<T> where T : Bar
{
public Bar Do(Bar obj)
{
return null;
}
protected abstract Bar Do(T obj);
}
public abstract class FooWithGoo<T> : Foo<T> where T : Bar
{
public FooWithGoo(string x)
{
}
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var mock = new Mock<FooWithGoo<Bar>>("abc");
FooWithGoo<Bar> foo = mock.Object;
}
[TestMethod]
public void TestMethod2()
{
var mock = new Mock<FooWithGoo<BarSub>>("abc");
FooWithGoo<BarSub> foo = mock.Object;
}
}
}
测试 1 失败,而测试 2 通过。
问题是通用抽象获得与具体方法相同的签名......我猜它会被混淆。
我能够使用提供的示例重现您的问题。
我通过将 Do
设为虚拟方法让 TestMethod1
通过。
public abstract class Foo<T> where T : Bar {
public virtual Bar Do(Bar obj) {
return null;
}
protected abstract Bar Do(T obj);
}
Moq 要求 public 方法是虚拟的或抽象的,以便能够模拟它们的实现。
我有两个这样的类
public abstract class Foo<T> where T : Bar {
public Bar Do(Bar obj) {
//I cast to T here and the call the protected one.
}
...
protected abstract Bar Do(T obj);
}
public abstract class FooWithGoo<T> : Foo<T> where T:Bar {
...
}
尝试在单元测试中使用 Moq 对此行进行模拟 new Mock<FooWithGoo<Bar>>()
给了我这个异常。
System.ArgumentException: Type to mock must be an interface or an abstract or non-sealed class. ---> System.TypeLoadException: Method 'Do' in type 'Castle.Proxies.FooWithGoo``1Proxy' from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.
我这里有什么地方做错了吗?我该如何嘲笑它?
更新: 这对我来说很好地说明了问题。
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
namespace UnitTestProject1
{
public class Bar
{
}
public class BarSub : Bar
{
}
public abstract class Foo<T> where T : Bar
{
public Bar Do(Bar obj)
{
return null;
}
protected abstract Bar Do(T obj);
}
public abstract class FooWithGoo<T> : Foo<T> where T : Bar
{
public FooWithGoo(string x)
{
}
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var mock = new Mock<FooWithGoo<Bar>>("abc");
FooWithGoo<Bar> foo = mock.Object;
}
[TestMethod]
public void TestMethod2()
{
var mock = new Mock<FooWithGoo<BarSub>>("abc");
FooWithGoo<BarSub> foo = mock.Object;
}
}
}
测试 1 失败,而测试 2 通过。 问题是通用抽象获得与具体方法相同的签名......我猜它会被混淆。
我能够使用提供的示例重现您的问题。
我通过将 Do
设为虚拟方法让 TestMethod1
通过。
public abstract class Foo<T> where T : Bar {
public virtual Bar Do(Bar obj) {
return null;
}
protected abstract Bar Do(T obj);
}
Moq 要求 public 方法是虚拟的或抽象的,以便能够模拟它们的实现。