Sử dụng phương pháp NUnit Assert.Throws hoặc thuộc tính ExpectedException?


146

Tôi đã phát hiện ra rằng đây dường như là hai cách thử nghiệm chính cho các trường hợp ngoại lệ:

Assert.Throws<Exception>(()=>MethodThatThrows());

[ExpectedException(typeof(Exception))]

Cái nào trong số này sẽ là tốt nhất? Có ai cung cấp lợi thế hơn người khác? Hay đơn giản chỉ là vấn đề sở thích cá nhân?


3
Lựa chọn thứ 3 là phong cách lưu loát:Assert.That(() => MethodThatThrows(), Throws.Exception)
Jack Ukleja 7/10/2016

1
NUnit phiên bản 3 trở lên không còn hỗ trợ ExpectedExceptionthuộc tính, vì vậy đối với phiên bản 3+ chỉ có Assert.Throwsbiến thể là phù hợp.
joanlofe

Tại sao nó như vậy? Đó là Nunit3 quyết định bỏ hỗ trợ đó? Đã googling xung quanh và không thể tìm thấy lời giải thích cho nó ... JUnit vẫn hỗ trợ theo cách này, phải không?
ahaaman

Câu trả lời:


91

Lần đầu tiên cho phép bạn kiểm tra nhiều hơn một ngoại lệ, với nhiều cuộc gọi:

Assert.Throws(()=>MethodThatThrows());
Assert.Throws(()=>Method2ThatThrows());

Thứ hai chỉ cho phép bạn kiểm tra một ngoại lệ cho mỗi chức năng kiểm tra.


25
Một bài kiểm tra chỉ nên kiểm tra một bit logic riêng biệt, vì vậy việc kiểm tra hai lỗi trong cùng một bài kiểm tra đơn vị có bị coi là thực hành xấu không?
SamuelDavis

5
@SamuelDavis - nói chung bạn sẽ không muốn kiểm tra các trường hợp khác nhau trong cùng một bài kiểm tra. Tuy nhiên, có thể có một số trường hợp sử dụng cho nhiều Assert.Throws.
chue x

3
Dù bằng cách nào, ở đây bạn lấy ngoại lệ làm tham số, cho phép bạn xác nhận chi tiết trong ngoại lệ. Ngoài ra, sử dụng "Ngoại lệ dự kiến" không bảo vệ bạn cho cùng loại ngoại lệ bị ném trong một cuộc gọi phương thức khác. Ở đây, bạn nhắm mục tiêu phương pháp chính xác và không phải toàn bộ bài kiểm tra. Mặc dù bài kiểm tra của bạn sẽ gọi rất ít mã, nhưng bạn không bao giờ quá an toàn. Đặc biệt là khi mã trở nên phức tạp và / hoặc ngoại lệ quá chung chung. Những thứ như "ArgumentNullExceptions" có thể bị ném đi rất nhiều và ví dụ có thể dễ dàng bị bỏ qua khi sử dụng ExpectedException. Khẳng định. Những cú ném sẽ không bỏ lỡ nó.
Gil Sand

254

Sự khác biệt chính là:

ExpectedException()thuộc tính làm cho kiểm tra được thông qua nếu ngoại lệ xảy ra ở bất kỳ nơi nào trong phương thức kiểm tra.
Việc sử dụng Assert.Throws()cho phép chỉ định exactvị trí của mã nơi dự kiến ​​ngoại lệ.

NUnit 3.0 giảm hỗ trợ chính thức ExpectedExceptionhoàn toàn.

Vì vậy, tôi chắc chắn thích sử dụng Assert.Throws()phương thức hơn là ExpectedException()thuộc tính.


7
Đây là câu trả lời đúng. Ngẫu nhiên, Assert.Throws () cũng trả về ngoại lệ, có thể cho phép kiểm tra bổ sung các thuộc tính của ngoại lệ, nếu chúng quan trọng với bạn.
cầu toàn

1
Cuối cùng trả lời lý do tại sao tôi không thể khiến ExpectedException hoạt động .. với phiên bản 3.
JanT

2
Đây là liên kết github.com/nunit/docs/wiki/Breaking- Thay đổi - ExpectedExceptionAttribution không còn được hỗ trợ.
Anton Lyhin

Để thay đổi điều này để hoạt động theo NUnit 3.0, hãy đổi nó thành như sau
Andrei Krasnutski

38

Tôi thích assert.throw vì nó cho phép tôi xác minh và khẳng định các điều kiện khác sau khi ngoại lệ được ném.

    [Test]
    [Category("Slow")]
    public void IsValidLogFileName_nullFileName_ThrowsExcpetion()
    {
        // the exception we expect thrown from the IsValidFileName method
        var ex = Assert.Throws<ArgumentNullException>(() => a.IsValidLogFileName(""));

        // now we can test the exception itself
        Assert.That(ex.Message == "Blah");

    }

Đây là một trong những câu trả lời tốt hơn, khá phổ biến là bạn muốn xác minh rằng một cái gì đó đã đi vào trạng thái bị lỗi sau khi ngoại lệ được ném.
Rhys Bevilaqua

10

Bạn cũng có thể gõ mạnh lỗi bạn mong đợi (như phiên bản attrib cũ).

Assert.Throws<System.InvalidOperationException>(() => breakingAction())

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.