如何使用 Moq 测试方法调用顺序
目前我有:
[Test]
public void DrawDrawsAllScreensInTheReverseOrderOfTheStack() {
// Arrange.
var screenMockOne = new Mock<IScreen>();
var screenMockTwo = new Mock<IScreen>();
var screens = new List<IScreen>();
screens.Add(screenMockOne.Object);
screens.Add(screenMockTwo.Object);
var stackOfScreensMock = new Mock<IScreenStack>();
stackOfScreensMock.Setup(s => s.ToArray()).Returns(screens.ToArray());
var screenManager = new ScreenManager(stackOfScreensMock.Object);
// Act.
screenManager.Draw(new Mock<GameTime>().Object);
// Assert.
screenMockOne.Verify(smo => smo.Draw(It.IsAny<GameTime>()), Times.Once(),
"Draw was not called on screen mock one");
screenMockTwo.Verify(smo => smo.Draw(It.IsAny<GameTime>()), Times.Once(),
"Draw was not called on screen mock two");
}
但是我在生产代码中绘制对象的顺序并不重要。我可以先做一个,也可以先做两个,没关系。然而,这应该很重要,因为抽奖顺序很重要。
您如何(使用起订量)确保按特定顺序调用方法?
编辑
我摆脱了那个测试。绘制方法已从我的单元测试中删除。我只需要手动测试它是否有效。不过,顺序的颠倒被纳入一个单独的测试类中进行了测试,所以这并不全是坏事。
感谢您提供有关他们正在研究的功能的链接。我当然希望它很快就会被添加,非常方便。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我最近创建了 Moq.Sequences,它提供了在 Moq 中检查订购的功能。您可能想阅读我的帖子,其中描述了以下内容:
setter 和 getter。
一次特定的呼叫应该是
预期的。
将呼叫分组到循环组中。
预计会出现循环次数。
按顺序可以相互混合
预计以任何顺序进行的呼叫。
典型用法如下:
I recently created Moq.Sequences which provides the ability to check ordering in Moq. You may want to read my post that describes the following:
setters and getters.
times a specific call should be
expected.
group calls into a recurring group.
of times a loop should be expected.
in sequence can be inter-mixed with
calls that are expected in any order.
Typical usage looks like:
使用 Moq CallBacks 的简单解决方案:
A simple solution using Moq CallBacks:
目前看来还没有实施。请参阅问题 24:MockSequence。 此帖子讨论了该问题。
不过,您可能会考虑修改您的测试。我通常认为测试顺序会导致测试脆弱,因为它经常测试实现细节。
编辑:我不确定这是否解决了OP的问题。卢塞罗的回答可能更有帮助。
It appears that it's not currently implemented. See Issue 24: MockSequence. This thread discusses the issue.
You might consider revising your tests, though. I generally feel that testing order leads to fragile tests, as it's often testing implementation details.
EDIT: I'm not sure that this addresses the OP's question. Lucero's answer may be more helpful.
看看这篇博客文章,它可能会解决您的问题问题。
Have a look at this blog post, it may solve your problem.
否则,您可以使用回调函数并增加/存储 callIndex 值。
Otherwise you could have used the Callback functions and increment/store a callIndex value.
从原来的帖子中,我可以假设测试方法执行以下操作调用:
其中“绘制”方法实现是这样的:
从我的角度来看,如果调用顺序非常重要,则应该引入附加结构(描述序列)进入系统。
最简单的实现:每个屏幕都应该知道他的后续元素,并在绘制自己之后调用其 Draw 方法:
从这一点开始,每个屏幕元素都应该了解另一点。这并不总是好的。如果是这样:您可以创建一些类,例如“ScreenDrawer”。该对象将存储自己的屏幕和后续屏幕(可能从 Screen 类继承他。使用其他世界:'ScreenDrawer'类描述系统结构。这是一个最简单的实现场景:
第二种方法引入额外的继承,但不需要 Screen 类 摘要:这两种方法都执行顺序
调用,并且不需要“序列”测试,而是需要测试当前“屏幕”是否调用另一个屏幕并测试“ScreenManager”是否调用“绘制”方法。 更可测试(可以使用大多数测试框架来实现,
这种方法:
。
From the original post I could assume that the testing method do the following operations call:
Where 'Draw' method implementation is something like this:
From my perspective, if the call order is very important then additional structure (that describe sequence) should be introduced into system.
The simplest implementation: each screen should know his subsequent element and call its Draw method after drawing himself:
From the one point, each Screen element should know a little about another one. This is not always good. If so: you can create some class like 'ScreenDrawer'. This object will store own screen and subsequent screen (probably inherit him from Screen class. Using other worlds: 'ScreenDrawer' class describes system structure. Here is a simplest scenario of implementation:
2nd method introduce additional inheritance, but doesn't required Screen class to know about his subsequence element.
Summary: both methods do sub-sequential calls and doesn't require 'sequence' testing. Instead they require testing if current 'screen' calls another one and testing if 'ScreenManager' calls 'Draw' method of the 1st element in sequence.
This approach:
Thanks.