一个示例 - 我想测试狙击手是否仅通知 View 添加的项目。
[Test]
public void NotifiesViewOfLoss_IfCloseEventReceivedForSnipedItems()
{
_sniper.AddItem(TestConstants.ItemNo54321);
_sniper.AddItem(TestConstants.ItemNo65432);
_sniper.AuctionClosedFor(TestConstants.ItemNo65432);
_mockView.Verify(view => view.UpdateStatus(TestConstants.ItemNo65432, AuctionSniperStatus.Lost));
_sniper.AuctionClosedFor(TestConstants.ItemNo54321);
_mockView.Verify(view => view.UpdateStatus(TestConstants.ItemNo54321, AuctionSniperStatus.Lost));
_sniper.AuctionClosedFor(7);
// doesn't work
//_mockView.Verify(view => view.UpdateStatus(It.IsAny<int>(), It.IsAny<AuctionSniperStatus>()),
// Times.Never() );
}
Times.Never 行不起作用 - 因为它与较早的调用之一匹配。 我知道还有其他选择:
- 设置一个新的期望,以便在调用时抛出(如上所示)
- 就像指定 7 而不是 IsAny()
- 将测试分为 2 个测试
最佳答案
在这种情况下,更新 View 上的状态不会给您任何可以断言的“结果”,我也会进行严格的模拟。通过这种方式,您可以准确设置您期望对模拟对象进行的调用(以及这些调用的确切数量)。当您更改模拟的类型时,您的测试将立即变得正确。
这种方式比你的前两种选择要好得多(因为即使你没有猜到正确的参数值或者忘记设置会抛出异常的期望,它也会导致测试失败),它也更具可读性(至少恕我直言)。
关于拆分测试,始终建议保持单元测试尽可能小。所以问题是,你想测试一下,当你在两次正确的调用之后出现这个错误的调用时会发生什么吗?或者仅仅有一个错误的调用就足够了?
关于unit-testing - 起订量:如何清除对模拟对象的期望?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3126749/