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

时间:2017-03-28 17:43:26

标签: c# unit-testing moq

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

我的遗留代码中有一个没有界面的类,当我'模拟&#39; ,我得到以下例外:

Additional information: Can not instantiate proxy of class: MyCompnay.Mylegacy.MyClass.

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

谢谢。

1 个答案:

答案 0 :(得分:9)

可以模拟具体类

[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());
  }

}

但是,

  • 必须是公共班级
  • 要模拟的方法必须是虚拟的

我收到的消息:

使课程内部

  

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

或者,使用非虚方法

  

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

与您的cannot instantiate消息不符,所以其他内容似乎有误。

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

e.g。

public class Foo
{

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

    public virtual int GetValue()
    {
        return _value;
    }
}

可以通过将值传递到Mock&lt;&gt;来解决这个问题。构造函数

e.g。

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