如何使用 Moq 验证调用类中的另一个方法
这看起来很简单,但我似乎无法让它发挥作用。
我有一个带有 Save 方法的类,该方法仅调用另一个方法 ShouldBeCalled()。我想验证如果我调用 Save() ,另一个方法 ShouldBeCalled() 至少会执行一次。我想我可以做以下事情。
public class ClassA
{
public virtual void Save()
{
ShouldBeCalled();
}
public virtual void ShouldBeCalled()
{
//This should get executed
}
}
[TestFixture]
public class ClassA_Test
{
[Test]
public void Save_Should_Call_ShouldBeCalled()
{
var mockClassA = new Mock<ClassA>();
mockClassA.Object.Save();
mockClassA.Verify(x => x.ShouldBeCalled(), Times.AtLeastOnce());
}
}
但我得到了异常“预期在模拟上调用至少一次,但从未执行过:x => x.ShouldBeCalled()”
这只是一个猜测,但 Moq 是否用它自己的版本覆盖 Save() 方法,该版本忽略我在真实对象的 Save() 方法中拥有的任何内容。
This seems like something simple but I can't seem to get it to work.
I have a class with a Save method that simply calls another method ShouldBeCalled(). I want to verify that if I call Save() that the other method ShouldBeCalled() is executed at least once. I thought that I could do the following.
public class ClassA
{
public virtual void Save()
{
ShouldBeCalled();
}
public virtual void ShouldBeCalled()
{
//This should get executed
}
}
[TestFixture]
public class ClassA_Test
{
[Test]
public void Save_Should_Call_ShouldBeCalled()
{
var mockClassA = new Mock<ClassA>();
mockClassA.Object.Save();
mockClassA.Verify(x => x.ShouldBeCalled(), Times.AtLeastOnce());
}
}
But I get the exception "Expected invocation on the mock at least once, but was never performed: x => x.ShouldBeCalled()"
It is just a guess but Is Moq overriding the Save() method with it's own version which ignores anything I have inside the real object's Save() method.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您遇到这个问题是因为您正在嘲笑正在测试的内容。这没有道理。
您是正确的,Moq 将用自己的方法替换您的方法的实现。原因是您应该使用 Moq 来模拟您正在测试的类调用的内容,而不是您正在测试的类本身。
如果您的代码是这样设计的,则此测试将是合适的:
现在这是该方法的正确测试:
这里的关键教训是您模拟/存根您的测试需要运行的内容,而不是您的内容正在测试自己。
希望这有帮助,
安德森
You are having this problem because you are mocking what you are testing. This doesn't make sense.
You are correct that Moq will replace the implementation of your method with its own. The reason is you are supposed to use Moq to mock things the class you are testing calls, not the class you are testing itself.
This test would be appropriate if your code were designed thusly:
And here is the correct test of that method now:
The key lesson here is that you mock/stub what your test needs to run, not what you are testing itself.
Hope this helps,
Anderson
尝试使用 CallBase = true,然后使用 false。我运行了你的代码并且它有效。
Try using the CallBase = true and then false. I ran your code and it works.
是的,这是可以做到的。但是,您需要添加一行代码以使 Moq 跟踪 ShouldBeCalled 方法是否确实被调用。
类似下面的内容将会起作用:
Setup 方法设置期望。当您致电验证时,您是在要求起订量验证这些期望。如果您没有进行安装调用来创建 ShouldBeCalled 方法的期望,那么 Moq 不会认为它是可跟踪的,因此当您尝试验证它时会严重失败。
Yes, this can be done. However, you need to add a line of code to have Moq track whether or not the ShouldBeCalled method was indeed called.
Something like the following will work:
The Setup method sets up expectations. When you call Verify, you are asking Moq to verify these expectations. If you don't make a Setup call to create expectations for the ShouldBeCalled method, then Moq doesn't consider it to be trackable and will therefore fail hard when you try to Verify it.
您可以使用
CallBase
。You can stub methods in the system under test using
CallBase
.