开发者

It.IsAny<Cart>(), It.IsAny<ShippingDetails>(), Times.Never(). What do they do?

开发者 https://www.devze.com 2023-04-06 17:16 出处:网络
I wonder if you could help me understand the following line: mock.Verify(m => m.ProcessOrder(It.IsAny<Cart>(),

I wonder if you could help me understand the following line:

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

The test method:

[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);
}


It.IsAny<Cart> matches any value of type Cart. Since you have Times.Never, you actually verify that the method has never been called with the two parameters (Card, ShippingDetails).


@Wiktor has it right, but just to clarify the difference.

The current check is making sure that the method has not been called with ANY cart or ANY shipping details. This might seem excessive, as perhaps this might be sufficient:

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

after all it is probable that the processing will be done with the given cart and shipping details. However it is possible that the cart could have been cloned, or some shipping details could have been loaded from the users preferences or something, and the It.IsAny<T> allows you to check that the method was not called regardless of the arguments, as otherwise the verification would only happen with those specific instances as arguments.

EDIT

To answer the comment. Imagine another test where instead you wanted to check that the order was processed, and that it was processed with the correct arguments and not with some different users cart and shipping details:

// 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());

now this tests fails if the ProcessOrder method is not called with exactly the same cart and shipping details that was expected. If it happened to use another users cart or shipping details then the test would fail.

Hope this clear up the difference between specifying the arguments explicitly and using It.IsAny<T>


It is verifying that the method ProcessOrder was never called using any type of Cart and ShippingDetails as arguments during the test.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号