2012-03-27 36 views
12

Tôi có một lớp tạo tệp.Sử dụng NUnit để kiểm tra bất kỳ loại ngoại lệ nào

Tôi hiện đang thực hiện các kiểm tra tích hợp để đảm bảo lớp học là ok.

Tôi đang chuyển vào thư mục và tên tệp không hợp lệ để đảm bảo ngoại lệ được ném.

Trong các thử nghiệm của tôi là tôi đang sử dụng:

[Test] 
public void CreateFile_InvalidFileName_ThrowsException() 
{ 
    //Arrange 
    var logger = SetupLogger("?\\"); 

    //Act 

    //Assert 
    Assert.Throws<Exception>(()=> logger.CreateFile()); 
} 

Tuy nhiên trong trường hợp này kiểm tra là không như một ArgumentException được ném. Tôi nghĩ bằng cách thêm vào Ngoại lệ nó sẽ vượt qua.

Có cách nào để vượt qua chỉ sử dụng Ngoại lệ không?

+1

Một lý do tại sao nó sẽ là một ý tưởng tốt để kiểm tra một ngoại lệ cụ thể là khách hàng của logger có thể sẽ muốn tránh phải nắm bắt những cơ sở lớp 'Exception', và do đó sẽ dựa vào một ngoại lệ đặc biệt bị ném, vì vậy đó là những gì bạn nên thử nghiệm. – Ergwun

Trả lời

21

Sự giúp đỡ cho Assert.Throws<> nói rằng nó "Thẩm tra một đại biểu ném một loại ngoại lệ khi được gọi là"

Hãy thử phiên bản Assert.That vì nó sẽ bắt bất kỳ Exception:

private class Thrower 
{ 
    public void ThrowAE() { throw new ArgumentException(); } 
} 

[Test] 
public void ThrowETest() 
{ 
    var t = new Thrower(); 
    Assert.That(() => t.ThrowAE(), Throws.Exception); 
} 
+0

+1 vì điều này thực sự trả lời câu hỏi, nhưng đừng bỏ qua lời khuyên tốt trong các câu trả lời khác để kiểm tra các ngoại lệ cụ thể. – Ergwun

+0

Nếu bạn cần kiểm tra các thuộc tính ngoại lệ hoặc gõ sau, bạn có thể làm: 'var ex = Assert.Throws (Is.AssignableTo (typeof (Ngoại lệ)),() => DoSomething());' –

1

Bạn có thể gắn thẻ phương pháp thử nghiệm của mình với thuộc tính ExpectedException. Cần làm việc.

[ExpectedException(typeof(Exception))] 
    public void TestException() 
    { 

    } 
+0

Sau khi đọc cuốn sách của Roy Osherove tôi cố gắng không sử dụng các thuộc tính – Jon

+0

Thú vị, tôi đã đọc thử nghiệm đơn vị thực dụng và họ khuyến khích sử dụng các thuộc tính (Và cá nhân tôi cũng sử dụng chúng). Hãy cẩn thận để giải thích tại sao không sử dụng chúng? Tôi muốn được hạnh phúc về một liên kết hoặc blog. – Alex

+0

Tôi không thể tìm thấy nó trong cuốn sách bây giờ vì vậy có lẽ đó là khóa học TDD của mình http://tekpub.com/productions/tdd – Jon

2

Ngoại lệ của bạn phải xác định và bạn có thể viết trường hợp kiểm tra thiết lập các điều kiện mà ngoại lệ cụ thể sẽ được ném và bạn nên kiểm tra ngoại lệ cụ thể đó.

Như vậy, thử nghiệm của bạn nên được viết lại như

CreateFile_InvalidFileName_ThrowsArgumentException 

Assert.Throws<ArgumentException>(() => logger.CreateFile()); 

Edit:

Bằng cách này, tôi nghĩ rằng constructor của bạn nên được phát hiện tên tập tin không hợp lệ và ném có . Và sau đó nó phải là một hợp đồng cho các nhà xây dựng rằng tên tập tin là hợp lệ.

+0

Tôi đồng ý nhưng có rất nhiều điều kỳ lạ để suy nghĩ và nhiều ngoại lệ có thể bị ném khi tạo tệp. Tôi tự hỏi nếu có bất kỳ thử nghiệm tích hợp sẵn bằng văn bản nào cho loại kịch bản này – Jon

+0

+1 Vì dù bạn không trả lời câu hỏi, tôi đồng ý với lời khuyên này. Các loại ngoại lệ mà lớp của bạn ném một phần của API công khai, và vì vậy nên được kiểm tra. – Ergwun

+0

@Jon, đồng ý rằng nó là một nỗi đau với số lượng các loại ngoại lệ khác nhau có thể được ném bởi một số phương pháp nhất định trong BCL. Nếu lớp logger của bạn muốn thân thiện hơn, nó có thể bắt các ngoại lệ đó và ném một ngoại lệ duy nhất (hoặc ít nhất là ít ngoại lệ) gói bản gốc như một ngoại lệ bên trong. Sau đó, bạn muốn thử nghiệm ngoại lệ đó một cách rõ ràng trong các thử nghiệm tự động của mình. – Ergwun

1

Nói chung, bạn chỉ nên kiểm tra các ngoại lệ cụ thể để đảm bảo mã của bạn phản hồi đúng cách với các lỗi khác nhau.

Nếu bạn thực sự cần cho phép bất kỳ trường hợp ngoại lệ nào vì thử nghiệm của mình, chỉ cần sử dụng khối try/catch tiêu chuẩn và xác nhận thành công/lỗi bình thường.

1

Viết phương pháp riêng của bạn và sử dụng nó để xác thực.

/// <summary> 
    /// Throwses the specified action. 
    /// </summary> 
    /// <typeparam name="T"></typeparam> 
    /// <param name="action">The action.</param> 
    /// <returns></returns> 
    public static T Throws<T>(Action action) where T : Exception 
    { 
     try 
     { 
      action(); 
     } 
     catch (T ex) 
     { 
      return ex; 
     } 

     Assert.Fail("Expected exception of type {0}.", typeof(T)); 
     return null; 
    } 
4

Đối với NUnit 2.5 trở lên

// Allow both ApplicationException and any derived type 
Assert.Catch<ApplicationException>(() => logger.CreateFile()); 

// Allow any kind of exception 
Assert.Catch(() => logger.CreateFile()); 
+0

'Assert.Catch ' giải quyết câu hỏi được hỏi tới dấu chấm * và *, như 'Assert.Throw ', cho phép một kết quả ngoại lệ là kết quả: 'var ex = Assert.Catch (() => ..); AssertMoreOnException (cũ); '. – user2864740

0

Throws.InstanceOf() cho phép bạn vượt qua một loại cơ sở ngoại lệ, thay vì một loại có nguồn gốc cụ thể hơn.

[Test] 
public void CreateFile_InvalidFileName_ThrowsException() 
{ 
    //Arrange 
    var logger = SetupLogger("?\\"); 

    //Act 

    //Assert 
    Assert.That(() => logger.CreateFile(), Throws.InstanceOf<Exception>()); 
} 
Các vấn đề liên quan