2012-12-26 25 views
5

जैसा कि this question में वर्णित है, मैं एक विधि पर काम कर रहा हूं जो एक List<FileInfo> से तत्व लौटाता है जो List<FileInfo> में मौजूद नहीं हैं।यह संग्रहAssert.AreEquivalent() परीक्षण क्यों विफल रहता है?

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; 
} 

मेरे SourceFiles के लिए डेटा सेट है:

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

DestFiles है: इस प्रकार मैं Nawfal के समाधान को क्रियान्वित किया है

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

जब मैं कोड के माध्यम से कदम और सूचियों की जांच 'मान, यह अपेक्षित परिणाम वापस करने के लिए प्रतीत होता है। लेकिन इकाई परीक्षण निम्न कोड के साथ विफल रहता है:

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); 
    } 

हालांकि result और expectedResult एक ही सामग्री है - दोनों सूचियों में एक ही फ़ाइल पथ और एक ही अन्य गुणों के साथ एक तत्व है - परीक्षण संदेश के साथ विफल :

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

expectedResultU:\folder1\d.txt के एक घटना है, हालांकि है। मैं सोच रहा था कि समस्या यह है कि मैं स्मृति वस्तुओं को उन वस्तुओं की सामग्री के बजाय दो वस्तुओं के लिए तुलना कर रहा हूं, लेकिन मैंने सोचा कि AreEquivalent() गुणों की तुलना कर रहा था। क्या यह मामला नहीं है?

संपादित करें: पतों की बजाय गुण की तुलना के बारे में सलाह के आधार पर, मैं इस जोर बजाय प्रयोग किया है, जो परीक्षा उत्तीर्ण करने की अनुमति दी:

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)); 
    } 

उत्तर

7

शायद क्योंकि FileInfo एक संदर्भ प्रकार और डिफ़ॉल्ट comparer सिर्फ चेकों है दो तत्वों के पते के बराबर होना चाहिए। चूंकि FileInfo सील कर दिया गया है, इसलिए आप इससे प्राप्त नहीं कर सकते हैं और समानता तुलनाकर्ताओं को ओवरराइड कर सकते हैं। मेरी राय में सबसे अच्छा विकल्प, आपकी खुद की संग्रह तुलनाकर्ता विधि लिख रहा होगा (क्योंकि आप IEqualityComparer उदाहरण CollectionAssert.AreEquivalent पर उदाहरण नहीं दे सकते हैं)।

4

परीक्षण विफल हो रहा है क्योंकि आपके संग्रह में उनमें अलग-अलग वस्तुएं हैं। यदि आपके पास FileInfo कक्षा के 2 उदाहरण हैं जो एक ही फ़ाइल को संदर्भित करते हैं, और आप instanceA.Equals(instanceB) पर कॉल करते हैं, तो परिणाम false है।

यदि आप FileInfo एस के बजाय स्ट्रिंग का उपयोग करने के लिए अपना कोड बदल सकते हैं, तो यह काम करेगा जैसा आप चाहते हैं।

1

2 दृष्टिकोण जो अपने मेरी राय :) में एक

  1. का चयन 2 फ़ाइल नाम के संग्रह से बेहतर हैं सुझाव है और इन संग्रहों की तुलना कर सकते हैं:

    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. उपयोग उपयोगकर्ता परिभाषित तुलनात्मक और तुलना FileInfo सूचियों:

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

दो foreach छोरों के साथ आपका वर्तमान implementaion निम्नलिखित मामले में असफल हो जायेगी नहीं:

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

expectedResult = 
    u:\folder1\a.txt 

हाँ, यह फ़ाइलों की सूची के लिए असली मामला हो प्रतीत नहीं होता है, लेकिन आम तौर पर यह एक अच्छा विचार नहीं है दो loops के साथ AreEquivalent()/Is.EquivalentTo() को प्रतिस्थापित करें।

संबंधित मुद्दे