简体   繁体   English

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

[英]Mocking an abstract class derived from an abstract class

I have two classes like this 我有两个这样的班

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 {
  ...
}

Trying to mock this in a unit test using Moq with this line new Mock<FooWithGoo<Bar>>() gives me this exception. 尝试在Moq的单元测试中new Mock<FooWithGoo<Bar>>()这一行, 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.

Is there something I am doing wrong here? 我在这里做错什么了吗? How can I mock this? 我该如何嘲笑?

UPDATE: This shows the problem nicely for me. 更新:这对我很好地显示了问题。

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;
    }
}
}

Test1 fails while test 2 passes. 测试2通过时,测试1失败。 The problem is that the generic abstract gets the same signature than the concrete method ... and it gets confused by that I guess. 问题在于,泛型摘要与具体方法具有相同的签名...我猜想对此感到困惑。

I was able to reproduce your issue with the example provided. 通过提供的示例,我能够重现您的问题。

I got TestMethod1 to pass by making Do a virtual method. 我通过将Do TestMethod1虚拟方法来使TestMethod1通过。

public abstract class Foo<T> where T : Bar {
    public virtual Bar Do(Bar obj) {
        return null;
    }
    protected abstract Bar Do(T obj);
}

Moq requires public methods to be either virtual or abstract in order to be able to mock their implementation. Moq要求公共方法是虚拟的或抽象的,以便能够模拟其实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM