【问题标题】:It.IsAny<Cart>(), It.IsAny<ShippingDetails>(), Times.Never(). What do they do?It.IsAny<Cart>()、It.IsAny<ShippingDetails>()、Times.Never()。他们在做什么?
【发布时间】:2011-09-21 17:15:21
【问题描述】:

我想知道您是否可以帮助我理解以下行:

        mock.Verify(m => m.ProcessOrder(It.IsAny<Cart>(), 
                                        It.IsAny<ShippingDetails>()),
                         Times.Never());

测试方法:

[TestMethod]
public void Cannot_Checkout_Empty_Cart()
{
    // Arrange - create a mock order processor
    Mock<IOrderProcessor> mock = new Mock<IOrderProcessor>();

    // Arrange - create an empty cart
    Cart cart = new Cart();

    // Arrange - create shipping details
    ShippingDetails shippingDetails = new ShippingDetails();

    // Arrange - create an instance of the controller
    CartController target = new CartController(null, mock.Object);

    // Act
    ViewResult result = target.Checkout(cart, shippingDetails);

    // Assert - check that the order hasn't been passed on to the processor
    mock.Verify(m => m.ProcessOrder(It.IsAny<Cart>(), It.IsAny<ShippingDetails>()), Times.Never());

    // Assert - check that the method is returning the default view
    Assert.AreEqual("", result.ViewName);

    // Assert - check that we are passing an invalid model to the view
    Assert.AreEqual(false, result.ViewData.ModelState.IsValid);
}

【问题讨论】:

    标签: c# unit-testing mocking moq


    【解决方案1】:

    It.IsAny&lt;Cart&gt; 匹配 Cart 类型的任何值。由于您拥有Times.Never,因此您实际上使用两个参数(Card、ShippingDetails)验证了该方法从未被调用过

    【讨论】:

      【解决方案2】:

      @Wiktor 说得对,但只是为了澄清区别。

      当前检查是确保没有使用 ANY 购物车或 ANY 运输详细信息调用该方法。这可能看起来有些过分,因为这可能就足够了:

      // Assert - check that the order hasn't been passed on to the processor
      mock.Verify(m => m.ProcessOrder(cart, shippingsDetails), Times.Never());
      

      毕竟,处理可能会使用给定的购物车和运输详细信息完成。但是,购物车可能已被克隆,或者某些运输详细信息可能已从用户首选项或其他内容中加载,并且It.IsAny&lt;T&gt; 允许您检查无论参数如何都未调用该方法,否则验证只会以这些特定实例作为参数进行。

      编辑

      回答评论。想象一下另一个测试,您想检查订单是否已处理,并且是否使用正确的参数进行处理,而不是使用某些不同的用户购物车和运输详细信息:

      // Arrange - create an empty cart
      Cart cart = new Cart();
      
      // Arrange - create shipping details
      ShippingDetails shippingDetails = new ShippingDetails();
      
      // Arrange - create an instance of the controller
      CartController target = new CartController(null, mock.Object);
      
      // Act
      ViewResult result = target.Checkout(cart, shippingDetails);
      
      //Assert - check the order was processed once with the 
      //correct cart and shipping details
      mock.Verify(m => m.ProcessOrder(cart, shippingDetails), Times.Once());
      

      现在,如果没有使用与预期完全相同的购物车和运输详细信息调用 ProcessOrder 方法,则此测试将失败。如果它碰巧使用了其他用户的购物车或运输详细信息,那么测试将失败。

      希望这能消除显式指定参数和使用 It.IsAny&lt;T&gt; 之间的区别

      【讨论】:

      • “否则验证只会在那些特定实例作为参数的情况下发生”,对不起,但这永远不会发生,对吧?它将如何匹配实例?而且它不依赖于任何值类型的标准,对吗?
      【解决方案3】:

      正在验证方法 ProcessOrder从未在测试期间使用任何类型的 CartShippingDetails 作为参数调用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-01-17
        • 1970-01-01
        • 2016-09-26
        • 1970-01-01
        • 2021-05-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多