0

私はデータを提供し、多くの配列を使用するAPIのテスターとして働くことになっているので、NUnit、LINQ、C#を使って練習することにしました。

actualネストされた配列を持つ配列であるGruopJoinの結果を「視覚化」するために、同等のexpectedオブジェクトを作成し、sを使用して比較していAssertます。

理想的には

 Assert.That( actual, Is.EqualTo( expected ) );

しかし、これは次のメッセージで失敗します。

NUnitExamples.TestFixture1.LinqOuterJoinMultirelation_Anon:期待値と実際値は両方ともインデックス[0]で値が異なります期待値:しかし、そうでした:

これは、オブジェクト参照が異なることを示していると思います。私が知りたいのは、それらは同等のオブジェクトですか、つまりプロパティ値はすべて等しいですか?

ネストされた配列とそのプロパティを含む配列要素のプロパティを歩くと、オブジェクトは同等ですが、非常に長い時間がかかる場合がわかります。同じことをする簡単な方法はありますか?

これが私のコードです(ところで、私はこれをすべて新しいものから学んでいるので、私のコードに対する批評は歓迎されます):

[Test]
public void LinqOuterJoinMultirelation_Anon()
{
    Course[] curriculum = 
    { 
        new Course() { CourseId = "C1", Title = "Database" },
        new Course() { CourseId = "C2", Title = "HCI" },
        new Course() { CourseId = "C3", Title = "Op Systems" },
        new Course() { CourseId = "C4", Title = "Programming" }
    };

    ExamMark[] results = 
    { 
        new ExamMark() { StudentId = "S1", CourseId = "C1", Mark = 85 },
        new ExamMark() { StudentId = "S1", CourseId = "C2", Mark = 49 },
        new ExamMark() { StudentId = "S1", CourseId = "C3", Mark = 85 },
        new ExamMark() { StudentId = "S2", CourseId = "C1", Mark = 49 },
        new ExamMark() { StudentId = "S3", CourseId = "C3", Mark = 66 },
        new ExamMark() { StudentId = "S4", CourseId = "C1", Mark = 93 }
    };

    var actual = curriculum.GroupJoin
    (
        results, 
        c => c.CourseId, 
        r => r.CourseId, 
        (c, r) => new Performance() { CourseId = c.CourseId, Results = r.ToArray<ExamMark>() }
    ).ToArray<Performance>();

    var expected = new[] 
    { 
        new Performance 
        { 
            CourseId = "C1", 
            Results = new[] 
            { 
                new ExamMark() { StudentId = "S1", CourseId = "C1", Mark = 85 }, 
                new ExamMark() { StudentId = "S2", CourseId = "C1", Mark = 49 },
                new ExamMark() { StudentId = "S4", CourseId = "C1", Mark = 93 }
            }
        },
        new Performance 
        { 
            CourseId = "C2", 
            Results = new[] 
            { 
                new ExamMark() { StudentId = "S1", CourseId = "C2", Mark = 49 }
            }
        },
        new Performance 
        { 
            CourseId = "C3", 
            Results = new[] 
            { 
                new ExamMark() { StudentId = "S1", CourseId = "C3", Mark = 85 },
                new ExamMark() { StudentId = "S3", CourseId = "C3", Mark = 66 }
            }
        },
        new Performance { CourseId = "C4" }
    };

    //Assert.That( actual, Is.EqualTo( expected ) );

    for (int i = 0; i < actual.Count(); i++)
    {
        Assert.That( actual[i].CourseId, Is.EqualTo( expected[i].CourseId ) );

        for (int j = 0; j < actual[i].Results.Count(); j++)
        {
            Assert.That( actual[i].Results[j].StudentId, Is.EqualTo( expected[i].Results[j].StudentId ) );
            Assert.That( actual[i].Results[j].CourseId, Is.EqualTo( expected[i].Results[j].CourseId ) );
            Assert.That( actual[i].Results[j].Mark, Is.EqualTo( expected[i].Results[j].Mark ) );
        }
    }


class Course
{
    public string CourseId { get; set; }
    public string Title { get; set; }
}

class ExamMark
{
    public string StudentId { get; set; }
    public string CourseId { get; set; }
    public int Mark { get; set; }
}

class Performance
{
    public string CourseId { get; set; }
    public ExamMark[] Results { get; set; }
}

解決済み

IEquatable<T>のオーバーライドを含む実装するクラスを変更し、オブジェクトがゼロ要素配列ではなくnull配列参照のために同等ではないEqualsことを発見しました。つまり、から変更する必要があります。expectedactual

new Performance { CourseId = "C4" }

new Performance { CourseId = "C4" , Results = new ExamMark[0] }

そして今Assert.That( actual, Is.EqualTo( expected ) );、意図したとおりに動作します:)

4

2 に答える 2

2

ExamMark適切なEqualsオーバーライドがあり(そしてそれはあるべきクラスのように見えます)、そしてあなたが持っていたPerformance(そしてまた、それを使用する実際のコードがそれを役立つと思うようなクラスのように見える)なら、あなたは使うことができます。

CollectionAssert.AreEqual(expected, actual);

それ以外の場合は、を定義しIEqualityComparer<Performance>て使用できます

CollectionAssert.AreEqual(expected, actual, new PerformanceComparer());

CollectionAssert.AreEquivalentテストされたコレクションが特定の順序であるかどうかを気にしない場合にも使用できます。

もちろん、Equalsメソッドは配列自体をウォークする必要がありますが、とにかく何かが必要です(もちろん、さまざまな長さでfalseを高速に返します)。

于 2012-08-31T09:27:09.027 に答える
0

まず、コレクションを比較するには、を使用することをお勧めしますCollectionAssert.AreEqual(IEnumerable expected, IEnumerable actual)

このメソッドには、2つのコレクション内の個々のアイテムの等価性チェックのためにIComparer実装を使用するオーバーロードがあります。これは1つのオプションであり、2つのオブジェクトを実装IComparerして比較するクラスを記述します。Performance

もう1つの方法は、すべてのクラスにIEquatableを実装させることです。次に、引数CollectionAssert.AreEqualなしで使用できます。IComparer

于 2012-08-31T09:28:16.327 に答える