简体   繁体   中英

Unit testing with Moq, using SequenceEqual to compare lists containing TimeSpans

I have a simple unit test method comparing 2 lists containing TimeSpan values, we also use Moq to initialize tests:

       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));
    }

This is how the TimeBand class looks like:

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

Assert.IsTrue(timeBandList.SequenceEqual(expected)); in the above test method is always returning false even though the 2 lists are identical, is the SequenceEqual right way of comparing 2 lists? If not is there any other way of comparing these lists?

Thanks

One can use SequenceEqual to compare the sets of TimeBands by implementing an EqualityComparer

private class TimebandEqualityComparer : IEqualityComparer<TimeBand>

or one can use CollectionAssert to compare them by implementing an IComparer

private class TimeBandComparer : IComparer

CollectionAssert gives a nicer message (indicating the first item that is different) but the IComparer is more messy that the EqualityComparer (in the example I gave -1 whether the lhs was 'bigger' or 'smaller' than the rhs; this is not correct but since all we really cared about was if they were the same it sufficed. (Though, admittedly, putting in a useful hash function for complex objects can be tedious too).

The important thing to remember is that unless the target (in this case TimeBand) implements IComparable or overrides the ==/equals members, the comparison is going to be on references so two lists of different objects, with the same values, will show up as different unless one uses a helper of some sort to compare them.

[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();
    }
}

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM