2014-01-24 22 views
1

我开始使用TDD(和MoQ)。我有一个方法接受订单并为该订单创建唯一的CustomerId。测试某种方法,并引发异常

public class CustomerService 
    { 

     public CustomerService(IOrderRepository orderRepo) 
     { 
      _orderRepo = orderRepo; 
     } 

     public string Create(Order order) 
     { 
      //1. Save the Order that comes in, irrespective of being valid or not. 
      _orderRepo.Save(order); 

      //2. If the order is invalid, throw an exception. 
      if (!isValid(order)) 
       throw new ArgumentException(); 

      //3. Create a Customer, generate a unique CustomerId and return that. 
      return createCustomerAndGenerateCustomerId(order); 
     } 

    } 

下面的测试似乎并不正确工作:

[Test] 
    [ExpectedException(typeof(ArgumentException))] 
    public void Create_WhenPassedInvalidOrder_StillPersistsIt() 
    { 
     //Arrange 
     var order = new Order(); //This is invalid, as it has some mandatory fields missing 
     var mockOrderRepo = new Mock<IOrderRepository>(); 
     var customerService = new CustomerService(mockOrderRepo.Object); 

     //Act 
     customerService.Create(order); //This should call Save() on the order repo, but still throw an exception. 

     //Assert 
     mockOrderRepo.Verify(o => o.Save(order), Times.Once()); 
    } 

这个测试总是通过,即使我不叫_orderRepo.Save()。我究竟做错了什么?

+0

你必须决定你想在您的测试断言什么:你想断言抛出了一个异常,还是你想断言你的'Save'方法被调用,因为在使用'ExpectedException'属性时你不能同时执行这两个操作...... – nemesv

+0

如果我尝试调试,程序执行并没有停止抛出新的ArgumentException(),而是继续沿着这个方法。这是由于ExpectedException? – Narayana

回答

1

在这种情况下,您不能使用ExpectedException,因为Nunit会在测试级别尝试/捕获异常,所以您的mockOrderRepo.Verify永远不会被调用。

所以,你需要手动尝试抓住你的customerService.Create电话 - 如果你想在抛出的异常手动断言 - 或者你的Assert.Throws if you're using Nunit 2.5 or higher

[Test] 
public void Create_WhenPassedInvalidOrder_StillPersistsIt() 
{ 
    //Arrange 
    var order = new Order(); 
    var mockOrderRepo = new Mock<IOrderRepository>(); 
    var customerService = new CustomerService(mockOrderRepo.Object); 

    //Act 
    Assert.Throws<ArgumentException>(() => customerService.Create(order)); 

    //Assert 
    mockOrderRepo.Verify(o => o.Save(order), Times.Once()); 
} 
+0

你的意思是排除'[ExpectedException(typeof(ArgumentException))]'而不是使用'Assert.Throws'? – Narayana

+0

是的,抱歉,我已经在示例代码中留下了属性,现在删除了。 – nemesv

+0

是的,现在我可以检查有效和无效的订单。谢谢! – Narayana

相关问题