替代NUnit中的数组行走数组?

时间:2012-08-31 09:08:20

标签: c# linq nunit

我将在一个提供数据并使用大量数组的API上担任测试人员,因此我决定使用NUnit,LINQ和C#进行一些练习。

为了帮助我'可视化'GruopJoin的actual结果,作为具有嵌套数组的数组,我正在制作一个等效的expected对象,然后使用Assert s进行比较

理想情况下我会使用

 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>,包括Equals的覆盖,并发现我的expected对象由于空数组引用而不是等效于actual零元素数组,即需要从

更改
new Performance { CourseId = "C4" }

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

现在Assert.That( actual, Is.EqualTo( expected ) );按预期工作:)

2 个答案:

答案 0 :(得分:2)

如果您的ExamMark有一个合适的Equals覆盖(并且它看起来应该是那种类),而您的Performance做了(并再次看起来像那种使用它的真实代码会发现有用的类,然后你可以使用。

CollectionAssert.AreEqual(expected, actual);

否则,您可以定义IEqualityComparer<Performance>并使用

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

如果您不关心按特定顺序测试的集合,也可以使用CollectionAssert.AreEquivalent

当然,Equals方法必须自己遍历数组,但无论如何都必须采取行动(当然,在不同的长度上快速返回false)。

答案 1 :(得分:0)

首先,要比较集合,最好使用CollectionAssert.AreEqual(IEnumerable expected, IEnumerable actual)

此方法存在重载,需要IComparer实现以对两个集合中的各个项进行等效检查。这是一个选项,编写一个实现IComparer的类并比较两个Performance个对象。

另一种选择是让所有类都实现IEquatable。然后,您可以使用CollectionAssert.AreEqual而不使用IComparer参数。