2012-06-05 22 views
16

Thông thường bạn kiểm tra, nếu một ngoại lệ được ném vào một phương pháp nhất định, như sau. tôi sử dụng FluentAssertions:Có thích hợp hơn để kiểm tra xem nhà xây dựng có ném ngoại lệ không?

[Fact] 
public void Exception_gets_thrown() 
{ 
    // Arrange 
    var foo = new Foo("validArgument"); 

    // Act/Assert 
    foo.Invoking(f => f.Bar(null))   // null is an invalid argument 
     .ShouldThrow<ArgumentNullException>(); 
} 

Nhưng làm thế nào để kiểm tra, nếu một ngoại lệ được ném vào các nhà xây dựng? Tôi chỉ làm như vậy, nhưng có cách nào phù hợp hơn qua FluentAssertions?

[Fact] 
public void Constructor_throws_Exception() 
{ 
    // Arrange 
    Action a =() => new Foo(null);   // null is an invalid argument 

    // Act/Assert 
    a.ShouldThrow<ArgumentNullException>(); 
} 
+2

Tôi không biết thư viện, nhưng tôi thích những gì bạn đã làm –

Trả lời

13

Đó chính là cách bạn đang phải kiểm tra cho trường hợp ngoại lệ và đó là những gì ShouldThrow<T>()ShouldNotThrow<T>() được thiết kế cho ở nơi đầu tiên. Thực tế, cách tiếp cận Invoking() có thể được đánh dấu là lỗi thời trong phiên bản lớn tiếp theo (2.0.0).

+0

Nhưng là nó đúng cách để kiểm tra, nếu một ngoại lệ được ném vào constructor? Thông qua hành động này? –

+1

Xấu hổ về việc lỗi thời phương thức Invoking(). Tôi thấy nó dễ đọc hơn nhiều so với cơ chế Action được hiển thị trong bài kiểm tra thứ hai ở trên. Gọi là giữ mọi thứ độc đáo với nhau để ý định là hiển nhiên. –

+0

@ebeen Tôi thường chỉ sử dụng [ExpectedException (typeof (ArgumentNullException))] khi kiểm tra các ngoại lệ được ném từ hàm tạo. Cho rằng chỉ có một dòng trong thử nghiệm, ngoại lệ chỉ có thể được ném từ đó. –

0

Tôi đã thêm một phương pháp helper như các nhà thầu bên dưới để sử dụng khi kiểm tra:

static Action Constructor<T>(Func<T> func) 
{ 
    return() => func(); 
} 

mà tôi sau đó sử dụng như thế này:

Constructor(() => new Foo("bar", null)) 
.ShouldThrow<ArgumentNullException>() 
.And 
.ParamName 
.Should() 
.Be("baz"); 

Tôi biết đó là một vấn đề của sở thích cá nhân, nhưng tôi tìm thấy điều này một chút sạch hơn cần phải khai báo và chỉ định một đại biểu đầu tiên.

Điều này sẽ làm cho đoạn code trong câu hỏi ban đầu trông như thế này:

[Fact] 
public void Constructor_throws_Exception() 
{  
    // Act/Assert 
    Constructor(() => new Foo(null)).ShouldThrow<ArgumentNullException>(); 
}