2014-06-25 19 views
6

Khi sử dụng Moq với Xác minh, để khẳng định rằng một phương thức nhất định đã được gọi với các tham số được chỉ định, có thể có các loại cú pháp khác nhau; một là "It" cú pháp, như thế nàyMoq Xác minh không có Nó - loại so sánh nào?

mock.Verify(c => c.SomeMethod(It.Is<string>(s => s == ExpectedString))); 

gì xảy ra ở đây là các thông số mà SomeMethod được gọi với, được kiểm tra cho sự bình đẳng với ExpectedString. Một cú pháp khác có thể là không có "Nó":

mock.Verify(c => c.SomeMethod(ExpectedString)); 

sẽ cho kết quả tương tự. Từ những gì tôi đã có thể tìm thấy trên các diễn đàn khác nhau, sự khác biệt là sau này là một kiểm tra xác định (tham chiếu bằng) (ngoại trừ các loại giá trị).

Tuy nhiên, câu hỏi của tôi là khi tham số thuộc loại Bộ sưu tập. Trong .NET, Equals trên Collection<T> chỉ là thừa hưởng từ object, do đó xác minh sau đây:

mock.Verify(c => c.SomeMethod(new Collection<string> { ExpectedString })); 

không nên có thể để vượt qua, cho rằng bộ sưu tập được khởi tạo trong xác minh, và do đó có thể không có thể là ví dụ tương tự được khởi tạo trong mã sản xuất. Tuy nhiên, nó hoạt động, mà chỉ ra rằng Moq hiện một CollectionAssert hoặc một cái gì đó như thế, trái với những thông tin tôi có thể tìm thấy.

Dưới đây là ví dụ mã minh họa hành vi, kiểm tra sẽ trôi qua, nhưng tôi nghĩ rằng nó sẽ thất bại nếu Moq đã sử dụng tham chiếu bằng so sánh.

[TestMethod] 
public void Test() 
{ 
    var mock = new Mock<IPrint>(); 
    const int ExpectedParam = 1; 
    var test = new TestPrinter { Printer = mock.Object, Expected = ExpectedParam }; 

    test.Do(); 

    mock.Verify(c => c.Print(new Collection<int> { ExpectedParam })); 
} 

public interface IPrint 
{ 
    void Print(Collection<int> numbers); 
} 

public class TestPrinter 
{ 
    public IPrint Printer { get; set; } 

    public int Expected { get; set; } 

    public void Do() 
    { 
     Printer.Print(new Collection<int> { Expected }); 
    } 
} 

Có ai biết nếu đây là hành vi mong đợi của Moq (phiên bản 4.1) không? Hành vi có thay đổi ở một số cấp phiên bản không?

Trả lời

5

Đây là desired behaviour và là added to moq in January 2009 (phiên bản 3.0.203.1).

Nếu moq tìm thấy một IEnumerable, nó sử dụng SequenceEqual để so sánh đối số thực tế và lập luận được sử dụng trong việc thiết lập, nếu không nó chỉ sử dụng Equals.

Here's các bit tương ứng của mã:

internal class ConstantMatcher : IMatcher 
{ 
    ... 

    public bool Matches(object value) 
    { 
     if (object.Equals(constantValue, value)) 
     { 
      return true; 
     } 

     if (this.constantValue is IEnumerable && value is IEnumerable) 
     { 
      return this.MatchesEnumerable(value); 
     } 

     return false; 
    } 

    private bool MatchesEnumerable(object value) 
    { 
     var constValues = (IEnumerable)constantValue; 
     var values = (IEnumerable)value; 
     return constValues.Cast<object>().SequenceEqual(values.Cast<object>()); 
    } 
} 
Các vấn đề liên quan