5

この質問で説明されているように、私はList<FileInfo>別のに存在しない要素を返すメソッドに取り組んでいますList<FileInfo>。Nawfalのソリューションを次のように実装しました。

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は次のとおりです。

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が(両方のリストに同じファイルパスと同じ他のプロパティを持つ1つの要素があります)、テストは次のメッセージで失敗します。

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

expectedResultただし、の発生はU:\folder1\d.txtあります。問題は、2つのオブジェクトの内容ではなく、2つのオブジェクトのメモリアドレスを比較していることだと思っていましたが、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));
    }
4

3 に答える 3

7

おそらく、FileInfoが参照型であり、デフォルトの比較子が 2 つの要素のアドレスが等しいことを確認するだけだからです。は封印されているためFileInfo、そこから派生して等値比較子をオーバーライドすることはできません。IEqualityComparer私の意見では、最良の選択肢は、独自のコレクション比較メソッドを作成することです (インスタンスを に渡すことができないためCollectionAssert.AreEquivalent)。

于 2012-12-26T22:48:16.630 に答える
4

コレクションに異なるオブジェクトが含まれているため、テストは失敗しています。FileInfo同じファイルを参照するクラスの 2 つのインスタンスがあり、を呼び出すinstanceA.Equals(instanceB)と、結果は になりfalseます。

s の代わりに文字列を使用するようにコードを変更できればFileInfo、期待どおりに動作します。

于 2012-12-26T22:49:48.970 に答える
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)))
    );
    

2 つの foreach ループを使用した現在の実装は、次の場合に失敗しません。

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

expectedResult =
    u:\folder1\a.txt

ええ、ファイル リストの実際のケースではないようですが、一般的に、AreEquivalent()/Is.EquivalentTo()を 2 つのループに置き換えることはお勧めできません。

于 2012-12-29T19:49:38.117 に答える