我可以使用moq Mock <MyClass>来模拟一个类,而不是一个接口吗?

n17*_*911 5 c# unit-testing moq

通过https://github.com/Moq/moq4/wiki/Quickstart,我看到它模拟了一个界面.

我的遗留代码中有一个没有接口的类,当我"模拟"时,我得到以下异常:

Additional information: Can not instantiate proxy of class: MyCompnay.Mylegacy.MyClass.
Run Code Online (Sandbox Code Playgroud)

如何使用Moq从Legacy代码中模拟类?

谢谢.

Ala*_*anT 13

可能的嘲笑具体类

[TestClass]
public class PlaceholderParserFixture
{

  public class Foo
  {
     public virtual int GetValue()
     {
        return 11;
     }
  }

  public class Bar
  {
     private readonly Foo _foo;

     public Bar(Foo foo)
     {
        _foo = foo;
     }

     public int GetValue()
     {
        return _foo.GetValue();
     }
  }

  [TestMethod]
  public void MyTestMethod()
  {
     var foo = new Mock<Foo>();
     foo.Setup(mk => mk.GetValue()).Returns(16);
     var bar = new Bar(foo.Object);

     Assert.AreEqual(16, bar.GetValue());
  }

}
Run Code Online (Sandbox Code Playgroud)

但,

  • 它必须是公共课
  • 要模拟的方法必须是虚拟的

我收到的消息:

使课程内部化

Castle.DynamicProxy.Generators.GeneratorException:类型MoqFixture + Foo不公开.无法为无法访问的类型创建代理.

或者,使用非虚方法

System.NotSupportedException:非虚拟(在VB中可覆盖)成员上的无效设置:mk => mk.GetValue()

不匹配你的cannot instantiate消息,所以别的东西似乎是错的.

如果在模拟对象上没有默认构造函数,则可以获得该错误消息

例如

public class Foo
{

    private int _value;
    public Foo(int value)
    {
       _value = value;
    }

    public virtual int GetValue()
    {
        return _value;
    }
}
Run Code Online (Sandbox Code Playgroud)

通过将值传递给Mock <> ctor,可以解决这个问题

例如

var foo = new Mock<Foo>(MockBehavior.Strict, new object[] { 11 });
Run Code Online (Sandbox Code Playgroud)

  • 该类不必是公共的。该错误消息说一些有关“可访问性”的信息。使用`[assembly:InternalsVisibleTo(“ DynamicProxyGenAssembly2”)]`,Moq可以访问您的内部组件,并且可以使用。 (2认同)