我有一个测试,我传入一个像这样的对象:
var repo = new ActualRepo();
var sut = new Sut(repo);
在我的测试中,Repo有一个我需要实际执行的方法,而另一个我想模拟而不执行的方法。
例如,请使用此伪代码:
var repo = new Mock<IRepo>();
repo.Setup(m => m.MethodIWantToCall()).WillBeExecuted();
repo.Setup(m => m.MethodIWantToMock()).Returns(false);
使用Moq,这是可能的,怎么做?
编辑: 我过去使用过TypeMock,你可以做类似的事情。
Isolator.When(() => repo.MethodToIgnore()).WillBeIgnored();
Isolator.When(() => repo.MethodToActuallyRun()).WillBeExecuted();
答案 0 :(得分:4)
问题不是很确定这是否有用但如果您要模拟的方法是虚拟,则可以部分模拟对象。
public class Foo {
public string GetLive() {
return "Hello";
}
public virtual string GetMock() {
return "Hello";
}
}
public class Snafu {
private Foo _foo;
public Snafu(Foo foo) {
_foo = foo;
}
public string GetMessage() {
return string.Format("{0} {1}", _foo.GetLive(), _foo.GetMock());
}
}
[TestMethod]
public void NotMocked() {
var snafu = new Snafu(new Foo());
Assert.AreEqual("Hello Hello", snafu.GetMessage());
}
[TestMethod]
public void Mocked() {
var mockFoo = new Mock<Foo>();
mockFoo.Setup(mk => mk.GetMock()).Returns("World");
var snafu = new Snafu(mockFoo.Object);
Assert.AreEqual("Hello World", snafu.GetMessage());
}
答案 1 :(得分:3)
如果使用相同的对象,除非其中一个方法是虚拟的并且您将模拟基于类型而不是接口,否则无法使用Moq执行此操作。
那是因为当您基于接口传递模拟对象时,您没有传递真实对象,因此它无法访问对象的实际方法。
您正在传递dynamic proxy,它将响应已设置响应的方法。
我相信TypeMock会在运行时重写程序集来实现这一点,Moq肯定不会这样做。
如果你想用Moq获得类似的结果:
编辑:我在阅读AlanT's answer后编辑了我的答案是否正确。