Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NUnit. Values differs at index [0]

I'm running a test, but if fails I don't know why:

Proj.Tests.StatTests.GetResults_RegularPage_ReturnListOfResults:
  Expected and actual are both <System.Collections.Generic.List`1[Proj.Classes.StatResult]> with 50 elements
  Values differ at index [0]
  Expected: <test;98318>
  But was:  <test;98318>

As you can see values are identical. Here is some code:

public class StatResult
    {
        public string word { get; set; }
        public UInt64 views { get; set; }

        public override string ToString()
        {
            return String.Format("{0};{1}", word, views);                
        }
    }    

    [Test]
    public void GetResults_RegularPage_ReturnListOfResults()
    {
        // Arrange            
        WordStat instance = new WordStat(Constants.WordStatRegularPage);
        // Act
        List<StatResult> results = instance.GetResults();
        // Assert
        Assert.AreEqual(results, new List<StatResult>
        {
            new WordStatResult { word ="test", views = 98318},
            new WordStatResult { word ="test board", views = 7801},
            //... I shorted it
        }

}

I tried a lot ways even putting test sample right into class, but it doesn't work anyway. Please help!

like image 514
kseen Avatar asked Mar 13 '12 14:03

kseen


3 Answers

The problem is the way NUnit is testing equality of the two instances of StatResult. Because you are not implementing any form of equality comparison operator, the equality check defaults to the reference of the instance. Because they are two different instances, their references are different.

See this article for more information on implementing equality in your objects.

like image 118
Randolpho Avatar answered Nov 15 '22 03:11

Randolpho


I can see that the two references refer to objects with equal properties, but that's not what's being tested here. It's checking that either they're references to the same object or that they're equal. Your StatResult class doesn't override Equals/GetHashCode, so two objects with the same values will be seen as "different" for testing.

You should override Equals and GetHashCode in order for two objects to be consider equal appropriately. I'd also suggest making the type immutable, as well as following normal .NET naming conventions for the properties:

public sealed class StatResult : IEquatable<StatResult>
{
    public string Word { get; private set; }
    public UInt64 Views { get; private set; }

    public StatResult(string word, ulong views)
    {
        this.word = word;
        this.views = views;
    }

    public override string ToString()
    {
        return String.Format("{0};{1}", word, views);                
    }

    public override int GetHashCode()
    {
        int hash = 23;
        hash = hash * 31 + Word == null ? 0 : Word.GetHashCode();
        hash = hash * 31 + Views.GetHashCode();
        return hash;
    }

    public override bool Equals(object other)
    {
        return Equals(other as StatResult);
    }

    public bool Equals(StatResult other)
    {
        return other != null &&
               this.Word == other.Word &&
               this.Views == other.Views;
    }
}

Your construction would just change to:

new StatResult("test", 98318),
new StatResult("test board", 7801),

(and likewise in your production code).

like image 29
Jon Skeet Avatar answered Nov 15 '22 02:11

Jon Skeet


You need to override Equals() and GetHashCode(). At the moment it is checking if the first item in each list is a reference to the same object.

like image 31
Trevor Pilley Avatar answered Nov 15 '22 04:11

Trevor Pilley