2012-12-26 47 views
5

Như được mô tả trong this question, tôi đang làm việc trên phương thức trả về các phần tử từ một số List<FileInfo> không có trong một số List<FileInfo> khác. Tôi đã thực hiện giải pháp Nawfal như sau:Tại sao kiểm tra CollectionAssert.AreEquivalent() này lại thất bại?

public List<FileInfo> SourceNotInDest(List<FileInfo> SourceFiles, List<FileInfo> DestFiles) 
{ 
var notInDest = SourceFiles.Where(c => !DestFiles.Any(p => p.Name == c.Name)).ToList(); 
return notInDest; 
} 

bộ dữ liệu của tôi cho SourceFiles là:

u:\folder1\a.txt 
u:\folder1\b.txt 
u:\folder1\c.txt 
u:\folder1\d.txt 

DestFiles là:

u:\folder2\a.txt 
u:\folder2\b.txt 
u:\folder2\c.txt 

Khi tôi bước qua mã và kiểm tra danh sách 'giá trị, điều này dường như trả về kết quả mong đợi. Tuy nhiên, kiểm tra đơn vị không thành công với đoạn mã sau:

public void SourceNotInDestTest() 
    { 
     //arrange 
     FileListComparer flc = new FileListComparer(); //class that has the list compare method 
     FolderReader fr = new FolderReader(); //class for getting FileInfo from folder 
     List<FileInfo> expectedResult = new List<FileInfo>(); 
     expectedResult.Add(new FileInfo(@"U:\folder1\d.txt")); 
     List<FileInfo> SourceFiles = fr.fileList(@"U:\folder1"); //gets the FileInfo for each file in the folder 
     List<FileInfo> DestFiles = fr.fileList(@"U:\folder2"); 


     //act 
     List<FileInfo> result = flc.SourceNotInDest(FTPFiles, LocalFiles); 

     //assert 
     CollectionAssert.AreEquivalent(result, expectedResult); 
    } 

Mặc dù resultexpectedResult có các nội dung tương tự - cả hai danh sách có một phần tử với các đường dẫn tập tin tương tự và cùng các tài sản khác - những thử nghiệm thất bại với thông điệp :

CollectionAssert.AreEquivalent failed. The expected collection contains 1 occurrence(s) 
of <U:\folder1\d.txt>. The actual collection contains 0 occurrence(s). 

expectedResult có sự xuất hiện của U:\folder1\d.txt. Tôi đã suy nghĩ có lẽ vấn đề là tôi đang so sánh các địa chỉ bộ nhớ cho hai đối tượng thay vì nội dung của các đối tượng đó, nhưng tôi nghĩ rằng AreEquivalent() đã so sánh các thuộc tính. đây không phải là trường hợp à?

EDIT: Dựa trên những lời khuyên về cách so sánh các thuộc tính thay vì địa chỉ, tôi đã sử dụng Khẳng định này thay vào đó, cho phép các thử nghiệm để vượt qua:

foreach (FileInfo fi1 in result) 
    { 
    Assert.IsNotNull(expectedResult.Find(fi2 => fi2.FullName == fi1.FullName)); 
    } 
foreach (FileInfo fi1 in expectedResult) 
    { 
    Assert.IsNotNull(result.Find(fi2 => fi2.FullName == fi1.FullName)); 
    } 

Trả lời

7

Có lẽ vì FileInfo là một loại tài liệu tham khảo và Comparer mặc định chỉ kiểm tra cho địa chỉ của hai phần tử bằng nhau. Kể từ khi FileInfo được niêm phong, bạn không thể lấy được từ nó và ghi đè lên các bộ so sánh bình đẳng. Tùy chọn tốt nhất, theo ý kiến ​​của tôi, sẽ viết phương pháp so sánh bộ sưu tập của riêng bạn (vì bạn không thể chuyển một ví dụ IEqualityComparer đến CollectionAssert.AreEquivalent).

4

Kiểm tra không thành công vì bộ sưu tập của bạn có các đối tượng khác nhau trong đó. Nếu bạn có 2 phiên bản của lớp FileInfo tham chiếu đến cùng một tệp và bạn gọi instanceA.Equals(instanceB), kết quả là false.

Nếu bạn có thể thay đổi mã của mình để sử dụng chuỗi thay vì FileInfo, nó sẽ hoạt động như bạn mong đợi.

1

Tôi có thể đề nghị 2 phương pháp đó là tốt hơn so với bạn một theo ý kiến ​​của tôi :)

  1. Chọn 2 bộ sưu tập của tên tập tin và so sánh các bộ sưu tập:

    CollectionAssert.AreEquivalent(
        result.Select(fi => fi.FullName).ToArray(), 
        expectedResult.Select(fi => fi.FullName).ToArray() 
    ); 
    // ToArray() is added just for better output when test fails. 
    
  2. Sử dụng người dùng định nghĩa so sánh và so sánh FileInfo danh sách:

    Assert.That(
        result, 
        Is 
         .EquivalentTo(expectedResult) 
         .Using((Comparison<FileInfo>)((fi1, fi2) => fi1.FullName.CompareTo(fi2.FullName))) 
    ); 
    

implementaion hiện tại của bạn với hai vòng foreach sẽ không thất bại trong trường hợp sau đây:

result = 
    u:\folder1\a.txt 
    u:\folder1\a.txt 

expectedResult = 
    u:\folder1\a.txt 

Yeah, nó dường như không phải là trường hợp thực sự cho danh sách các tập tin, nhưng generaly nó không phải là một ý tưởng tốt để thay thế AreEquivalent()/Is.EquivalentTo() bằng hai vòng lặp.

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