2010-11-02 29 views
30

Tôi đã một giao diện định nghĩa làMOQ - thiết lập một phương pháp dựa trên các giá trị tham số (nhiều lý lẽ)

interface IMath 
{ 
AddNumbersBetween(int lowerVal, int upperVal); 
} 

tôi có thể thiết lập một Moq cơ bản cho các bên trên như sau:

Mock<IMath> mock = new Mock<IMath>();  
mock.Setup(m => m.AddNumbersBetween(It.IsAny<int>(), It.IsAny<int>())); 

cuộc gọi nó

mock.Object.AddNumbersBetween(1,4); 

và sau đó xác nhận rằng nó đã được gọi là

mock.Verify(m => m.AddNumbersBetween(1,4), Times.AtleastOnce()); 

tôi không thể tìm ra cách để thiết lập các AddNumbersBetween phương pháp như vậy mà nếu upperVal thấp hơn lowerVal một ngoại lệ được ném

mock.Object.AddNumbersBetween(4,1);//should throw an exception 

Về cơ bản tìm kiếm cái gì đó như:

mock.Setup(foo => foo.AddNumbersBetween("arg1 is higher than arg2")).Throws<ArgumentException>(); 
+1

Tôi khuyên bạn chỉ nên triển khai logic loại trừ ngoại lệ với Gọi lại, vì điều đó cho phép bạn truy cập đầy đủ vào cả hai tham số. Theo như tôi biết, các mệnh đề khớp tham số chỉ có thể thực hiện logic dựa trên một tham số duy nhất. –

Trả lời

62

Tôi biết đây là một năm cũ, nhưng tôi tìm thấy một cách để sử dụng nhiều thông số với phiên bản mới nhất của Moq ít nhất:

mock.Setup(x => x.Method(It.IsAny<int>(), It.IsAny<int>()) 
    .Returns<int, int>((a, b) => a < b); 
+0

+1, nhưng bạn có lỗi đánh máy. Bạn cần đặt một '=>' giữa '(a, b)' và '{return a NightOwl888

+1

Cảm ơn, có vẻ như Piotr đã chăm sóc nó nhờ. – Gustyn

+1

Đẹp, đã làm việc cho tôi! – willem

8

Đối phương pháp đối số đơn lẻ, cách thức sạch sẽ nhất là:

mock.Setup(foo => foo.Submit(IsLarge())).Throws<ArgumentException>(); 
... 
public string IsLarge() 
{ 
    return Match<string>.Create(s => !String.IsNullOrEmpty(s) && s.Length > 100); 
} 

Không thể áp dụng điều này nếu phương thức có nhiều đối số. Hiện vẫn còn là một 'workaround' có thể được sử dụng, bắt chước những gì bạn muốn đạt được:

/// <summary> 
/// Tests if a moq can send an exception with argument checking 
///</summary> 
[TestMethod] 
public void TestException() 
{ 
    Mock<IMath> mock = new Mock<IMath>(); 
    mock.Setup(m => m.AddNumbersBetween(It.IsAny<int>(), It.IsAny<int>())); 

    mock.Setup(foo => foo.AddNumbersBetween(It.IsAny<int>(), It.IsAny<int>())) 
     .Callback<int, int>((i, j) => CheckArgs(i, j)); 

    try 
    { 
     mock.Object.AddNumbersBetween(1, 2); 
    } 
    catch (Exception ex) 
    { 
     // Will not enter 
     Console.WriteLine("Exception raised: {0}", ex); 
    } 
    try 
    { 
     mock.Object.AddNumbersBetween(2, 1); 
    } 
    catch (Exception ex) 
    { 
     // Will enter here, exception raised 
     Console.WriteLine("Exception raised: {0}", ex); 
    } 
} 

private bool CheckArgs(int i, int j) 
{ 
    if(i > j) 
     throw new ArgumentException(); 
    return true; 
} 
+0

Điều này chỉ hoạt động trên một tham số duy nhất và không có nhiều tham số –

+0

Lỗi của tôi ... có một cách khác để xử lý việc này, với một cuộc gọi lại sẽ ném ngoại lệ nếu các đối số không vượt qua xác thực của bạn. Tôi đã chỉnh sửa câu trả lời của mình bằng phương pháp đó – srodriguez

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