0

我有一个简单的单元测试方法,比较包含 TimeSpan 值的 2 个列表,我们还使用 Moq 来初始化测试:

       private IRepository _RepositoryTimeBand;

       [TestInitialize]
       public void TestInit()
       {
        var TimeBandSet = new List<TimeBand>
            {
                new TimeBand() {StartTime = new TimeSpan(7, 30, 0), EndTime = new TimeSpan(16, 0, 0)},
                new TimeBand() {StartTime = new TimeSpan(19, 0, 0), EndTime = new TimeSpan(21, 0, 0)}
            };

        var RepositoryMoq = new Mock<IRepository>();

        RepositoryMoq.Setup(
            mr =>
            mr.GetTimeBand().Returns(TimeBandSet);

        _RepositoryTimeBand = RepositoryMoq.Object;


       [TestMethod]
    public void GetTimeBand_ExpectListOfTimeBandReturned()
    {
        var expected = new List<TimeBand>
            {
                new TimeBand {StartTime = new TimeSpan(7, 30, 0), EndTime = new TimeSpan(16, 0, 0)},
                new TimeBand {StartTime = new TimeSpan(19, 0, 0), EndTime = new TimeSpan(21, 0, 0)}
            };

        var timeBandList = _RepositoryTimeBand.GetTimeBand();

        Assert.IsNotNull(timeBandList);
        Assert.IsTrue(timeBandList.SequenceEqual(expected));
    }

这就是 TimeBand 类的样子:

public class TimeBand
{
    public TimeSpan StartTime { get; set; }
    public TimeSpan EndTime { get; set; }
}

Assert.IsTrue(timeBandList.SequenceEqual(expected));在上面的测试方法中,即使 2 个列表相同,也总是返回 false SequenceEqual,比较 2 个列表的正确方法是什么?如果没有,还有其他方法可以比较这些列表吗?

谢谢

4

1 回答 1

1

可以使用SequenceEqual通过实现EqualityComparer来比较 TimeBands 集

private class TimebandEqualityComparer : IEqualityComparer<TimeBand>

或者可以使用CollectionAssert通过实现IComparer来比较它们

private class TimeBandComparer : IComparer

CollectionAssert 提供了更好的消息(指示第一个不同的项目),但 IComparer 比 EqualityComparer 更混乱(在示例中,我给出了 -1,无论 lhs 是 rhs 是“大”还是“小”;这是不正确的但是因为我们真正关心的只是它们是否相同就足够了(虽然,诚然,为复杂对象添加一个有用的散列函数也可能很乏味)。

要记住的重要一点是,除非目标(在本例中为 TimeBand)实现 IComparable 或覆盖 ==/equals 成员,否则比较将在引用上进行,因此两个具有相同值的不同对象列表将显示除非使用某种助手来比较它们,否则它们是不同的。

[TestClass]
public class ComparingTimespans {

    [TestMethod]
    public void CompareTimeBandTwoListsAreSameUsingCollectionAssert() {

var lhs = new List<TimeBand>
{
    new TimeBand { StartTime = new TimeSpan(1,1,1) , EndTime = new TimeSpan(2,2,2)},
          new TimeBand { StartTime = new TimeSpan(3,3,3) , EndTime = new TimeSpan(4,4,4)},
      };

var rhs = new List<TimeBand>
{
    new TimeBand { StartTime = new TimeSpan(1,1,1) , EndTime = new TimeSpan(2,2,2)},
    new TimeBand { StartTime = new TimeSpan(3,3,3) , EndTime = new TimeSpan(4,4,4)},
      };


CollectionAssert.AreEqual(lhs, rhs, new TimeBandComparer());

}

[TestMethod]
public void CompareTimeBandTwoListsAreSameUsingSequenceEquals() {

    var lhs = new List<TimeBand>
    {
new TimeBand { StartTime = new TimeSpan(1,1,1) , EndTime = new TimeSpan(2,2,2)},
new TimeBand { StartTime = new TimeSpan(3,3,3) , EndTime = new TimeSpan(4,4,4)},
    };

    var rhs = new List<TimeBand>
    {
 new TimeBand { StartTime = new TimeSpan(1,1,1) , EndTime = new TimeSpan(2,2,2)},
 new TimeBand { StartTime = new TimeSpan(3,3,3) , EndTime = new TimeSpan(4,4,4)},
    };

    Assert.IsTrue(lhs.SequenceEqual(rhs, new TimebandEqualityComparer()));

}


private class TimeBand {
    public TimeSpan StartTime { get; set; }
    public TimeSpan EndTime { get; set; }
}

private class TimeBandComparer : IComparer {

   public int Compare(object x, object y) {
var xTb = x as TimeBand;
var yTb = y as TimeBand;
return (xTb.StartTime == yTb.StartTime && xTb.EndTime == yTb.EndTime)
         ? 0
         : -1;
   }
}

private class TimebandEqualityComparer : IEqualityComparer<TimeBand> {
    public bool Equals(TimeBand x, TimeBand y) {
return x.StartTime == y.StartTime && x.EndTime == y.EndTime;
    }

    public int GetHashCode(TimeBand obj) {
return obj.StartTime.GetHashCode() ^ obj.EndTime.GetHashCode();
    }
}

}

于 2013-02-21T13:40:13.440 回答