2013-04-17 31 views
13

Tôi làm việc với khung moq cho thử nghiệm của mình. Tôi có một kịch bản trong đó tôi mong đợi một ngoại lệ lỗi được ném. Làm thế nào tôi có thể xác minh nó đã được ném?MOQ - xác minh ngoại lệ đã được ném

public void Koko(List<string?> list) 
{ 
    foreach(string? str in list) 
    { 
     if (str != null) someProperty.Foo(str); 
     else throw new FormatException(); 
    } 
} 

Xin cảm ơn trước.

+0

Hiển thị công việc của bạn .. Mọi người không thể đọc được suy nghĩ của bạn. Vui lòng đọc [FAQ] và [yêu cầu] cũng .. –

Trả lời

6

Vui lòng đọc số Introduction to Moq này. Dưới đây là cách để thiết lập InvalidOperationException ném khi phương pháp DoSomething được gọi:

mock.Setup(foo => foo.DoSomething()).Throws<InvalidOperationException>(); 

Sau đó chỉ cần kiểm tra xem phương pháp được gọi. Nếu nó được gọi, sau đó ngoại lệ được nâng lên

mock.Verify(foo => foo.DoSomething()); 
+0

Tôi không muốn thiết lập ngoại lệ. Tôi muốn xác minh nó không bị ném. –

+0

@GZ bạn đang cố gắng xác minh xem Moq có hoạt động không? Nếu bạn thiết lập ngoại lệ ném nó sẽ được ném nếu phương thức được gọi. Chỉ cần xác minh xem phương thức đã được gọi hay chưa. –

+0

Tôi sẽ giải thích kịch bản chi tiết hơn. Có lẽ cách tiếp cận của tôi là không chính xác. Tôi có vòng lặp foreach chạy trên hai đối tượng. Một là có sẵn và một là null. Tôi muốn xác minh hai điều, phương pháp đầu tiên chạy trên đối tượng có sẵn và một ngoại lệ được ném cho đối tượng null (Trong phương pháp tôi kiểm tra null và nếu ném ngoại lệ theo cách thủ công). –

6

Bạn có thể kiểm tra rằng một ngoại lệ được ném sử dụng NUnit Khẳng định:

Assert.That(() => testObject.methodToTest(), Throws.TypeOf<FaultException>()); 
18

Nếu bạn muốn xác minh một ngoại lệ được ném (bằng mã riêng của bạn) sau đó Moq không phải là công cụ của bạn lựa chọn cho điều đó. Chỉ cần sử dụng một trong các khung kiểm tra đơn vị có sẵn.

xUnit/NUnit

Khẳng định thạo

Action act =() => foo.Bar()); 
act.ShouldThrow<SomeException>() 

http://fluentassertions.codeplex.com/documentation

http://www.nunit.org/index.php?p=exceptionAsserts&r=2.6.2

0

Ok vì vậy tôi giải quyết nó theo cách sau.

Kể từ khi ngoại lệ đã phá vỡ thử nghiệm của tôi, tôi đặt lệnh gọi phương thức trong khối Vì khi thử.

Sau đó, tôi có thể sử dụng Xác minh đơn giản.

Nhờ tất cả những người giúp đỡ ...

+4

Cân nhắc đăng bài của bạn mã giải pháp, như những người khác có thể học hỏi từ nó hoặc bình luận về nó. Bạn cũng có thể đánh dấu câu trả lời này là giải pháp. –

+2

giống như AlanT có câu trả lời đúng. Trong Moq nếu bạn muốn kiểm tra 'Foo (string)' sẽ ném 'ArgumentException', bạn nên sử dụng' ExpectedException' – steve

18

Tôi có thể là mis-đọc ý định của bạn, nhưng như xa như tôi có thể thấy không cần phải làm gì để một mô hình để kiểm tra rằng các ngoại lệ đã được ném.

Dường như bạn có một lớp với một Foo phương pháp mà phải mất một chuỗi - cho phép gọi InnerClass này

public class InnerClass { 
    public virtual void Foo(string str) { 
     // do something with the string 
    } 
} 

và một lớp học, trong đó có một InnerClass như một tài sản (someProperty) trong đó có một thành viên Koko rằng phải mất một chuỗi Danh sách < > như một tham số

public class OuterClass { 

    private readonly InnerClass someProperty; 

    public OuterClass(InnerClass someProperty) { 
     this.someProperty = someProperty; 
    } 

    public void Koko(List<string> list) { 
     foreach (var str in list) { 
       if (str != null) 
        someProperty.Foo(str); 
       else 
        throw new FormatException(); 
      } 
    } 
} 

LƯU Ý: tôi không thể nhận Danh sách < chuỗi? > để biên dịch - cho tôi biết loại (chuỗi) cơ bản phải không có giá trị. AFAIK, người ta chỉ cần tạo các kiểu giá trị nullable, các kiểu tham chiếu hoàn toàn không có giá trị.

Dường như bạn muốn kiểm tra xem liệu bạn có vượt qua trong danh sách các chuỗi mà bất kỳ giá trị nào trong số đó không có giá trị mà một lỗi định dạng được ném ra hay không.

Nếu vậy, lý do duy nhất cho MOQ là giải phóng chúng tôi khỏi lo lắng về chức năng InnerClass. Foo là một phương pháp, vì vậy, trừ khi chúng tôi đang sử dụng mocks nghiêm ngặt, chúng tôi chỉ có thể tạo ra một mô hình InnerClass không có thiết lập khác.

Có một thuộc tính [ExpectedException] mà chúng tôi có thể gắn thẻ thử nghiệm của mình để xác minh rằng ngoại lệ đã được ném.

[TestMethod] 
[ExpectedException(typeof(FormatException))] 
public void ExceptionThrown() { 

    var list = new List<string>() { 
     "Abel", 
     "Baker", 
     null, 
     "Charlie" 
    }; 

    var outer = new OuterClass(new Mock<InnerClass>().Object); 
    outer.Koko(list); 

} 

Thử nghiệm này sẽ vượt qua nếu nhận dạng định dạng được ném và thất bại nếu không.

+0

Tôi không biết về thuộc tính ExpectedException, điều này thật tuyệt! Cảm ơn. – chrjs

+0

Đây là câu trả lời thực sự. Cảm ơn – CubanTurin

5

Một câu hỏi cũ nhưng không có mã nguồn thực hiện những giải pháp là, vì vậy đây là những gì tôi đã làm:

var correctExceptionThrown = false; 

try 
{ 
    _myClass.DoSomething(x); 
} 
catch (Exception ex) 
{ 
    if (ex.Message == "Expected message") 
     correctExceptionThrown = true; 
}      

Assert.IsTrue(correctExceptionThrown); 

Lưu ý chứ không phải là kiểm tra tin nhắn, bạn có thể bắt một loại ngoại lệ (thường thích hợp hơn) .

Các vấn đề liên quan