Why is this test unit pass?

北战南征 提交于 2019-12-11 20:38:54

问题


I spend over 2 hours on this... i can't figure out why this test is PASSING. I mean.. it shouldnt return the view "Completed" but in the test it does! It say Expected "string.Empty" but returned "Completed" however for the creditcard to pass.. the securitycode need to be "test" which is isnt at all in the test. So it should return the default view (which is like view();).

What i am doing wrong ? it is my test that is wrong ? or the controller logic ?

Thanks a lots.


[Test]
public void Cannot_Check_Out_If_Credit_Card_Failed_To_Process()
{
 var mockOrderSubmitter = new Mock<IOrderSubmitter>();
 var mockCreditCardProcessor = new Mock<ICreditCardProcessor>();

 // Arrange: Given a user has a non-empty cart
 var cart = new Cart();
 cart.AddItem(new Product(), 1);

 // Arrange: ... but the credit card failed to process
 var cartController = new CartController(null, mockOrderSubmitter.Object, mockCreditCardProcessor.Object);
 var result = cartController.CheckOut(cart, new ShippingDetails(), new CreditCard() { SecurityCode = "123" });

 // Assert
 result.ShouldBeDefaultView();
}

[HttpPost]
public ActionResult CheckOut(Cart cart, ShippingDetails shippingDetails, CreditCard creditCard)
{
  // Empty carts can't be checked out
  if (cart.Lines.Count == 0)
      ModelState.AddModelError("Cart", "Sorry, your cart is empty!");

  // Everything is valid
  if (ModelState.IsValid)
  {
      // Effectue le paiement.
      TransactionResult result = creditcardProcessor.TakePayment(creditCard, cart.ComputeTotalValue());
      if (result == TransactionResult.Success)
      {
          // Envoi la commande
          orderSubmitter.SubmitOrder(cart, shippingDetails);
          cart.Clear();
          return View("Completed");
      }
      else
      {
          ModelState.AddModelError("CreditCard", "Sorry, we couldn't process your credit card, please verify your credit card details and retry.");
          return View(new CheckOutViewModel());
      }

  }
  else // Something was invalid
      return View(new CheckOutViewModel());
}

public class MainCreditCardProcessor : ICreditCardProcessor
{
    public TransactionResult TakePayment(CreditCard card, decimal amount)
    {
        if (card.SecurityCode == "test")
            return TransactionResult.Success;
        else
            return TransactionResult.TransactionDeclined;
    }
}


回答1:


I found a solution to my problem. To help others poeple that might have the same problem i will explain it.

The problem was with my test. Since mocks objects are empty objects with no methods inside, zero logics. That mean that the test actually doesn't use an instance of the MainCreditCarDProcessor. (I didn't know about that)

So i had to setup the mock for this particular test by adding :

// Arrange: Given we have a creditcard processor that return TransactionDeclined.
mockCreditCardProcessor.SetReturnsDefault(TransactionResult.TransactionDeclined);

To force it to return TransactionDeclined,, through this is not "forcing" since its a mock you just set it up to return that value otherwise i guess it will return the default value it find.. which in this case was 0 the first element of the enum or null for other kind of method that return others kind of values.

If anything i said is wrong please correct me.

Thanks.




回答2:


The test will fail if ShouldBeDefaultView() throws.



来源:https://stackoverflow.com/questions/4686814/why-is-this-test-unit-pass

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!