Assert to compare two lists of objects C#

前端 未结 3 790
梦谈多话
梦谈多话 2021-01-14 17:13

I am currently trying to learn how to use unit testing, and I have created the actual list of 3 animal objects and the expected list of 3 animal objects. The question is how

相关标签:
3条回答
  • 2021-01-14 17:26

    I am of the opinion that implementing the IEqualityComparer (Equals() and GetHashCode()) for only testing purpose is a code smell. I would rather use the following assertion method, where you can freely define that on which properties you want to do the assertions:

    public static void AssertListEquals<TE, TA>(Action<TE, TA> asserter, IEnumerable<TE> expected, IEnumerable<TA> actual)
    {
        IList<TA> actualList = actual.ToList();
        IList<TE> expectedList = expected.ToList();
    
        Assert.True(
            actualList.Count == expectedList.Count,
            $"Lists have different sizes. Expected list: {expectedList.Count}, actual list: {actualList.Count}");
    
        for (var i = 0; i < expectedList.Count; i++)
        {
            try
            {
                asserter.Invoke(expectedList[i], actualList[i]);
            }
            catch (Exception e)
            {
                Assert.True(false, $"Assertion failed because: {e.Message}");
            }
        }
    }
    

    In action it would look like as follows:

        public void TestMethod()
        {
            //Arrange
            //...
    
            //Act
            //...
    
            //Assert
            AssertAnimals(expectedAnimals, actualAnimals);
        }
    
        private void AssertAnimals(IEnumerable<Animal> expectedAnimals, IEnumerable<Animal> actualAnimals)
        {
            ListAsserter.AssertListEquals(
                (e,a) => AssertAnimal(e,a),
                expectedAnimals,
                actualAnimals);
        }
    
        private void AssertAnimal(Animal expected, Animal actual)
        {
            Assert.Equal(expected.Name, actual.Name);
            Assert.Equal(expected.Weight, actual.Weight);
            //Additional properties to assert...
        }
    

    I am using XUnit for the simple Assert.True(...) and Assert.Equals(), but you can use any other unit test library for that. Hope it helps someone! ;)

    0 讨论(0)
  • 2021-01-14 17:40

    That is correct, as the lists are 2 different objects containing the similar data.

    In order to get compare lists you should use the CollectionAssert

    CollectionAssert.AreEqual(expected ,actual);
    

    That should do the trick.

    0 讨论(0)
  • 2021-01-14 17:42

    Just incase someone comes across this in the future, the answer was I had to create an Override, IEqualityComparer as described below:

    public class MyPersonEqualityComparer : IEqualityComparer<MyPerson>
    {
    public bool Equals(MyPerson x, MyPerson y)
    {
        if (object.ReferenceEquals(x, y)) return true;
    
        if (object.ReferenceEquals(x, null)||object.ReferenceEquals(y, null)) return false;
    
        return x.Name == y.Name && x.Age == y.Age;
    }
    
    public int GetHashCode(MyPerson obj)
    {
        if (object.ReferenceEquals(obj, null)) return 0;
    
        int hashCodeName = obj.Name == null ? 0 : obj.Name.GetHashCode();
        int hasCodeAge = obj.Age.GetHashCode();
    
        return hashCodeName ^ hasCodeAge;
    }
    

    }

    0 讨论(0)
提交回复
热议问题