代码之家  ›  专栏  ›  技术社区  ›  Gishu

Moq:如何清除对模拟对象的期望?

  •  2
  • Gishu  · 技术社区  · 14 年前

    举个例子——我想测试狙击手是否只为添加的物品通知视图。

    [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线路不起作用-因为它与前面的一个呼叫相匹配。 我知道还有其他选择:

    • 设置一个调用时抛出的新期望(如上所示)
    3 回复  |  直到 14 年前
        1
  •  2
  •   Grzenio    14 年前

    在这种情况下,更新视图上的状态不会给您任何可以断言的“结果”,我也会选择严格的模拟。你就这么定了 确切地

    这种方法比前两个选项要好得多(因为即使您猜不到正确的参数值或忘记设置引发异常的期望值,它也会使测试失败),而且可读性更高(至少IMHO)。

    关于拆分测试,始终建议将单元测试保持尽可能小。所以问题是,您想测试在两次正确的呼叫之后,如果您有这个错误的呼叫,会发生什么情况吗?或者仅仅有一个错误的电话就足够了?

        2
  •  1
  •   David M    14 年前

    如果你想断言 您指定的方法被调用,您可能需要考虑使用 _mockView 在这个测试中。

        3
  •  1
  •   Community holdenweb    7 年前

    https://stackoverflow.com/a/23549214/179311 ):

    _sniper.AuctionClosedFor(TestConstants.ItemNo54321);
    _mockView.Verify(view => view.UpdateStatus(TestConstants.ItemNo54321, AuctionSniperStatus.Lost));
    
    _mockView.ResetCalls();
    
    _sniper.AuctionClosedFor(7);
    _mockView.Verify(view => view.UpdateStatus(It.IsAny<int>(), It.IsAny<AuctionSniperStatus>()),
                     Times.Never() );