Moq,模拟抽象类:模拟对象不能使用抽象类中实现的方法
嗨,我有一个类似于以下内容的代码:
public abstract class MyAbstractClass
{
public virtual string DoSomething(string s1, string s2)
{
return this.DoSomethingElse(s1 + s2);
}
protected abstract string DoSomethingElse(string s);
}
[TestMethod]
public void Test()
{
var myMock = new Mock<MyAbstractClass>();
myMock.Protected().Setup<string>("DoSomethingElse", ItExpr.IsAny<string>()).Returns<string>(x => $"{x} I did it.");
var result = myMock.Object.DoSomething("a", "b");
}
我希望测试中的结果是“ab我做到了”,但我得到了一个空值。我注意到,如果删除“DoSomething”方法中的“虚拟”,它会按预期返回。问题是我需要这个方法是虚拟的。老实说,根据我对起订量如何工作的理解,它应该返回“ab我做到了”,但也许我错过了一些东西。
有什么想法吗?谢谢
hi I have a code similar to the following:
public abstract class MyAbstractClass
{
public virtual string DoSomething(string s1, string s2)
{
return this.DoSomethingElse(s1 + s2);
}
protected abstract string DoSomethingElse(string s);
}
[TestMethod]
public void Test()
{
var myMock = new Mock<MyAbstractClass>();
myMock.Protected().Setup<string>("DoSomethingElse", ItExpr.IsAny<string>()).Returns<string>(x => quot;{x} I did it.");
var result = myMock.Object.DoSomething("a", "b");
}
I would expect the result in the test to be "ab I did it", but I get back a null. I noticed that if remove the "virtual" to the "DoSomething" method, than it would return as expected. The problem is that I need this method to be virtual. And honestly in my understanding of how moq work it should return the "ab I did it", but maybe I am missing something.
Any idea? Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
原因是因为您正在使用模拟对象调用
DoSomething
方法,但是因为您没有告诉模拟对象使用真正的实现或Setup
它默认情况下只是“不执行任何操作”(即返回 null)。解决此问题的快速方法是为模拟对象设置 CallBase = true 属性。然后,任何不是
Setup
的方法都将使用真正的实现。这将打印“DoSomething: DoSomethingElseResult”,这应该正是您想要的。模拟对象使用真实实现来运行
DoSomething
,而DoSomething
的真实实现则运行DoSomethingElse
的模拟实现。The reason is because you're calling the
DoSomething
method using the mock object, but because you haven't told the mock object to use the real implementation orSetup
it, it's just going to "do nothing" (ie return null) by default.The quick way to solve this is by setting the
CallBase = true
property for the mock object. Then, any method that isn'tSetup
will use the real implementation.This will print "DoSomething: DoSomethingElseResult", which should be exactly what you want. The mock object runs
DoSomething
using the real implementation, and the real implementation ofDoSomething
runs the mocked implementation ofDoSomethingElse
.