1

I am very new using Moq and unit tests.

I have been watching videos and reading different articles but I can't find the right example.

I am trying to mock a method that returns list of a object, but I'm getting this error

Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException: 'Assert.AreEqual failed.
Expected:<System.Collections.Generic.List'1[BusinessLayer.Model.XSIPhoneTrunkDetails]>. Actual:<System.Collections.Generic.List'1[BusinessLayer.Model.XSIPhoneTrunkDetails]>.

This is my code:

Controller:

public List<XSIPhoneTrunkDetails> GetTrunksRange(LocationVM location)
{
    //var response = false;
    List<XSIPhoneTrunkDetails> newDetails = new List<XSIPhoneTrunkDetails>();
    if (!string.IsNullOrWhiteSpace(location.TrunksRange) && !location.TrunksRange.Equals("[]"))
    {
        var xSIPhoneTrunkDetails = JsonConvert.DeserializeObject<List<XSIPhoneTrunkDetails>>(location.TrunksRange);

        foreach (var item in xSIPhoneTrunkDetails)
        {
            if (item.RangeStart.Equals(item.RangeEnd))
                item.RangeEnd = String.Empty;

            if (item.XSIPhoneTrunkDetailsID <= 0)
                newDetails.Add(item);
        }
    }
    return newDetails;
}

Interface:

public interface ILocation
{
    List<XSIPhoneTrunkDetails> GetTrunksRange(LocationVM location);
}

My unit test

[Fact]
public void ShouldGetTrunkRange()
{
    using (var mock = AutoMock.GetLoose())
    {
        var phone = GetLocationVMsNotRange().First();
        var item = new List<BusinessLayer.Model.XSIPhoneTrunkDetails>();

        mock.Mock<ILocation>()
           .Setup(x => x.GetTrunksRange(phone))
           .Returns(item);

        var cls = mock.Create<Location>();

        var result = cls.GetTrunksRange(phone);
        Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(item.ToList(), result.ToList());
    }
}

What am I doing wrong?

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
G4bri3l
  • 19
  • 3
  • Remove the `ToList()` call. – Alexander Petrov Oct 06 '22 at 01:34
  • @AlexanderPetrov still getting the error :( – G4bri3l Oct 06 '22 at 02:38
  • Have you deleted both `ToList()` calls? `Assert.AreEqual(item, result)` – Alexander Petrov Oct 06 '22 at 10:39
  • Try using FluentAssertions with the statement "Should().BeEquivalentTo()", which checks for value equality instead of reference equality: https://fluentassertions.com/objectgraphs/ – Sarah Oct 06 '22 at 12:21
  • Or `CollectionAssert` which does the same thing. – Greg Burghardt Oct 06 '22 at 12:22
  • `List<>` is a reference type, and if `XSIPhoneTrunkDetails` is a class, then it will also be a reference type. Unless you provide overloads for equality, e.g. [`IEquatable<>`](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/how-to-define-value-equality-for-a-type#class-example), or use a `record` (which defines value type equality for top level properties automatically) ,default reference type equality is simply the reference (address) of the object, which will always be false unless both references are to the same allocated instance. – StuartLC Oct 11 '22 at 07:23
  • The above item equality issue is in addition to the second issue, which is how to compare 2 collections - as mentioned MSTest has [CollectionAssert.AreEqual / AreEquivalent](https://stackoverflow.com/q/11055632/314291) and Linq has [SequenceEqual](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.sequenceequal?view=net-7.0) – StuartLC Oct 11 '22 at 13:06

1 Answers1

0

Use loop to iterate through the list and assert individual objects like this,

Assert.True(item.Equals(result));

If you use loop:

Assert.True(item[0].Equals(result[0]));

the code is not exact just to give you an idea.

Also another thing you can assert the list count or property values of the objects using loop. Do what works, good luck!

Abdullah Rana
  • 415
  • 2
  • 10