2010-03-19 48 views
6

Tôi mới sử dụng NUnit và đang tìm kiếm giải thích tại sao thử nghiệm này không thành công?NUnit, CollectionAssert.AreEquivalent (..., ...), C# Câu hỏi

Tôi nhận được ngoại lệ sau khi chạy thử nghiệm.

NUnit.Framework.AssertionException: dự kiến: tương đương với < < .... ExampleClass>, < .... ExampleClass>> Nhưng là: < < .... ExampleClass>, < ... .ExampleClass>>

using NUnit.Framework; 
using System.Collections.ObjectModel; 

public class ExampleClass 
{ 
    public ExampleClass() 
    { 
     Price = 0m; 
    } 

    public string Description { get; set; } 
    public string SKU { get; set; } 
    public decimal Price { get; set; } 
    public int Qty { get; set; } 
} 

[TestFixture] 
public class ExampleClassTests 
{ 
    [Test] 
    public void ExampleTest() 
    { 

     var collection1 = new Collection<ExampleClass> 
       { 
        new ExampleClass 
         {Qty = 1, SKU = "971114FT031M"}, 
        new ExampleClass 
         {Qty = 1, SKU = "971114FT249LV"} 
       }; 

     var collection2 = new Collection<ExampleClass> 
       { 
        new ExampleClass 
         {Qty = 1, SKU = "971114FT031M"}, 
        new ExampleClass 
         {Qty = 1, SKU = "971114FT249LV"} 
       }; 

     CollectionAssert.AreEquivalent(collection1, collection2); 

    } 
} 

Trả lời

10

Để xác định xem 2 bộ sưu tập có bằng nhau NUnit cuối cùng phải so sánh các giá trị trong bộ sưu tập. Trong trường hợp này, các giá trị thuộc loại ExampleClassclass. Nó không thực hiện bất kỳ kiểm tra bình đẳng (chẳng hạn như trọng Overals và GetHashCode) để NUnit cuối cùng sẽ làm một so sánh tham chiếu. Điều này sẽ thất bại vì mỗi bộ sưu tập chứa các phiên bản khác nhau của Example mặc dù các trường có cùng giá trị.

Bạn có thể khắc phục điều này bằng cách thêm vào sau vào ExampleClass

public override bool Equals(object o) { 
    var other = o as ExampleClass; 
    if (other == null) { return false; } 
    return this.Description == other.Description 
    && this.SKU == other.SKU 
    && this.Price == other.Price 
    && this.Qty == other.Qty; 
} 

public override int GetHashCode() { return 1; } 

Lưu ý: Tôi chọn giá trị 1 cho GetHashCode vì đây là một loại có thể thay đổi và giá trị trả về chỉ thực sự an toàn cho GetHashCode trên một loại có thể thay đổi là một hằng số. Nếu bạn có ý định sử dụng điều này như là một chìa khóa trong một Dictionary<TKey,TValue> mặc dù bạn sẽ muốn xem lại điều này.

6

bạn cần phải thực hiện EqualsGetHashCode trên ExampleClass của bạn. Nếu không có điều đó, NUnit đang làm một kiểm tra bình đẳng tham chiếu ("là những đối tượng chính xác cùng?"), Không phải là một giá trị bình đẳng một ("làm các đối tượng này trông giống nhau?").

+2

Triển khai Chỉ bằng với mục đích thử nghiệm có thể giới thiệu ô nhiễm bình đẳng: http://xunitpatterns.com/Test%20Logic%20in%20Production.html#Equality Pollution –

+0

Tôi đã cố định ghi đè Bằng và thử nghiệm mẫu của tôi hoạt động. Vì vậy, nó chỉ là thực hành tốt để ghi đè lên GetHashCode() phương pháp hoặc là nó cần thiết cho một số lý do khác? Cảm ơn! –

+1

Việc triển khai 'GetHashCode' cần đồng ý với' Equals': nếu hai đối tượng giống nhau, chúng phải có cùng mã băm. (Hai đối tượng có thể có cùng mã băm ngay cả khi chúng khác nhau, nhưng nếu các đối tượng khác nhau có cùng mã băm, 'Equals' phải trả về false.) –