浏览https://github.com/Moq/moq4/wiki/Quickstart,我看到它模拟了一个接口。
我的遗留代码中有一个没有接口的类。当我
Mock<MyClass>
时,我得到以下异常:
附加信息:无法实例化类的代理:MyCompnay.Mylegacy.MyClass。
如何使用 Moq 从遗留代码中模拟类?
它是可以模拟具体类
[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 => mk.GetValue()
与您的
cannot instantiate
消息不匹配,因此其他内容似乎有问题。
如果模拟对象上没有默认构造函数,您可能会收到该错误消息
例如
public class Foo
{
private int _value;
public Foo(int value)
{
_value = value;
}
public virtual int GetValue()
{
return _value;
}
}
可以通过将值传递到 Mock<> ctor 来解决这个问题
例如
var foo = new Mock<Foo>(MockBehavior.Strict, new object[] { 11 });
Moq 无法为大多数具体类(也称为密封类或非虚拟成员)进行模拟。您可以使用库 MockMe 模拟此类类(免责声明:我是作者)。
使用它的 API(希望)非常直观
using MockMe;
var mock = Mock.Me(default(MyRepo)); // rebuild test project after writing this to help IDE fill in IntelliSense
mock.Setup.ExpensiveDatabaseCall().Returns(99);
MyRepo myRepo = mock.MockedObject;
var result = myRepo.ExpensiveDatabaseCall();
Assert.Equal(99, result);
mock.Assert.ExpensiveDatabaseCall().WasCalled();