As described in this question, I'm working on a method that returns the elements from one List<FileInfo>
that are not present in another List<FileInfo>
. I've implemented Nawfal's solution as follows:
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;
}
My data set for SourceFiles is:
u:\folder1\a.txt
u:\folder1\b.txt
u:\folder1\c.txt
u:\folder1\d.txt
DestFiles is:
u:\folder2\a.txt
u:\folder2\b.txt
u:\folder2\c.txt
When I step through the code and examine the lists' values, this appears to return the expected result. But the unit test fails with the following code:
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);
}
Even though result
and expectedResult
have the same contents--both lists have one element with the same file path and same other properties--the test fails with the message:
CollectionAssert.AreEquivalent failed. The expected collection contains 1 occurrence(s)
of <U:\folder1\d.txt>. The actual collection contains 0 occurrence(s).
expectedResult
does have an occurrence of U:\folder1\d.txt
, though. I was thinking maybe the problem is that I'm comparing the memory addresses for two objects instead of the contents of those objects, but I thought the AreEquivalent()
was comparing properties. Is that not the case?
EDIT: Based on the advice about comparing properties instead of addresses, I used this Assert instead, which allowed the test to pass:
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));
}
Probably because FileInfo
is a reference type and the default comparer just checks for the two elements' addresses to be equals. Since FileInfo
is sealed, you can't derive from it and override the equality comparers. The best option, in my opinion, would be writing your own collection comparer method (since you can't pass an IEqualityComparer
instance to CollectionAssert.AreEquivalent
).
The test is failing because your collections have different objects in them. If you have 2 instances of the FileInfo
class that refer to the same file, and you call instanceA.Equals(instanceB)
, the result is false
.
If you could change your code to use strings instead of FileInfo
s, it would work as you expect it to.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With