2014-01-24 23 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

相關問題