2012-12-26 13 views
5

Come descritto in this question, sto lavorando a un metodo che restituisce gli elementi da uno List<FileInfo> non presenti in un altro List<FileInfo>. Ho implementato la soluzione di Nawfal come segue:Perché questo test CollectionAssert.AreEquivalent() fallisce?

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

Il mio set di dati per SourceFiles è:

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

DestFiles è:

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

Quando faccio un passo attraverso il codice ed esaminare le liste 'valori, questo sembra restituire il risultato atteso. Ma il test di unità non riesce con il seguente codice:

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

Anche se result e expectedResult hanno gli stessi contenuti - entrambe le liste hanno un elemento con lo stesso percorso del file e altre proprietà stesse - la prova non riesce con il messaggio :

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

expectedResult ha un'occorrenza di U:\folder1\d.txt, però. Stavo pensando che forse il problema è che sto confrontando gli indirizzi di memoria per due oggetti invece del contenuto di quegli oggetti, ma ho pensato che il AreEquivalent() stesse confrontando le proprietà. Non è questo il caso?

EDIT: Sulla base del parere sul confronto proprietà invece di indirizzi, ho usato questa asserzione, invece, che ha permesso la prova da superare:

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

risposta

7

Probabilmente perché FileInfo è un tipo di riferimento e l'operatore di confronto di default solo controlli perché gli indirizzi dei due elementi siano uguali. Poiché FileInfo è sigillato, non è possibile derivarne e ignorare i comparatori di uguaglianza. L'opzione migliore, a mio parere, sarebbe scrivere il proprio metodo di confronto delle raccolte (dato che non è possibile passare un'istanza IEqualityComparer a CollectionAssert.AreEquivalent).

4

Il test ha esito negativo perché le raccolte contengono oggetti diversi. Se si dispone di 2 istanze della classe FileInfo che si riferiscono allo stesso file e si chiama instanceA.Equals(instanceB), il risultato è false.

Se fosse possibile modificare il codice per utilizzare le stringhe anziché FileInfo s, funzionerebbe come previsto.

1

posso suggerire 2 approcci che sono meglio dei vostri uno a mio parere :)

  1. Select 2 collezioni di nomi di file e confrontare questi collezioni:

    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. Usa definita dall'utente confronta e confronta FileInfo liste:

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

tuo implementaion corrente con due loop foreach non mancherà nei seguenti casi:

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

expectedResult = 
    u:\folder1\a.txt 

Sì, non sembra essere vero e proprio caso per la lista di file, ma Generaly non è una buona idea sostituire AreEquivalent()/Is.EquivalentTo() con due anelli.

Problemi correlati