模拟从抽象类派生的抽象类

本文关键字:抽象类 派生 模拟 | 更新日期: 2023-09-27 18:00:12

我有两个类似的类

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要求公共方法要么是虚拟的,要么是抽象的,以便能够模拟它们的实现。