2010-03-19 6 views
6

Ich bin neu bei NUnit und suche nach einer Erklärung, warum dieser Test fehlschlägt?NUnit, CollectionAssert.AreEquivalent (..., ...), C# -Frage

Ich bekomme die folgende Ausnahme beim Ausführen des Tests.

NUnit.Framework.AssertionException: Erwartet: entspricht < < .... ExampleClass>, < .... ExampleClass>> Aber war: < < .... ExampleClass>, < ... .ExampleClass>>

using NUnit.Framework; 
using System.Collections.ObjectModel; 

public class ExampleClass 
{ 
    public ExampleClass() 
    { 
     Price = 0m; 
    } 

    public string Description { get; set; } 
    public string SKU { get; set; } 
    public decimal Price { get; set; } 
    public int Qty { get; set; } 
} 

[TestFixture] 
public class ExampleClassTests 
{ 
    [Test] 
    public void ExampleTest() 
    { 

     var collection1 = new Collection<ExampleClass> 
       { 
        new ExampleClass 
         {Qty = 1, SKU = "971114FT031M"}, 
        new ExampleClass 
         {Qty = 1, SKU = "971114FT249LV"} 
       }; 

     var collection2 = new Collection<ExampleClass> 
       { 
        new ExampleClass 
         {Qty = 1, SKU = "971114FT031M"}, 
        new ExampleClass 
         {Qty = 1, SKU = "971114FT249LV"} 
       }; 

     CollectionAssert.AreEquivalent(collection1, collection2); 

    } 
} 

Antwort

10

Um festzustellen, ob 2 Sammlungen gleich sind, muss NUnit eventuell die Werte in der Sammlung vergleichen. In diesem Fall sind die Werte vom Typ ExampleClass, der eine class ist. Es implementiert keine Gleichheitsprüfungen (wie das Überschreiben von Equals und GetHashCode), so dass NUnit schließlich einen Referenzvergleich durchführt. Dies schlägt fehl, da jede Auflistung verschiedene Instanzen von Example enthält, obwohl die Felder dieselben Werte haben.

Sie konnten dieses Problem beheben, die folgenden auf den ExampleClass

public override bool Equals(object o) { 
    var other = o as ExampleClass; 
    if (other == null) { return false; } 
    return this.Description == other.Description 
    && this.SKU == other.SKU 
    && this.Price == other.Price 
    && this.Qty == other.Qty; 
} 

public override int GetHashCode() { return 1; } 

Hinweis durch Hinzufügen: Ich habe den Wert 1 für GetHashCode entschieden, weil dies ein veränderlichen Typ ist und der einzigen wirklich sichere Rückgabewert für GetHashCode auf einem wandelbaren Typ ist eine Konstante. Wenn Sie beabsichtigen, dies als Schlüssel in einem Dictionary<TKey,TValue> zu verwenden, sollten Sie dies jedoch noch einmal überprüfen.

6

Sie benötigen Equals und GetHashCode auf Ihrem ExampleClass zu implementieren. Ohne dies macht NUnit eine Referenz-Gleichheitsüberprüfung ("Sind das die gleichen Objekte?"), Keine Gleichheit ("Sehen diese Objekte ähnlich aus?").

+2

Die Implementierung von Equals ausschließlich für Testzwecke kann Gleichheit Pollution einführen: http://xunitpatterns.com/Test%20Logic%20in%20Production.html#Equality Pollution –

+0

Ich habe die Equals override behoben und mein Beispieltest funktioniert. Also, ist es einfach eine gute Methode, die GetHashCode() Methode zu überschreiben oder ist es aus einem anderen Grund notwendig? Vielen Dank! –

+1

Die 'GetHashCode'-Implementierung muss mit' Equals 'übereinstimmen: Wenn zwei Objekte gleich sind, müssen sie denselben Hash-Code haben. (Zwei Objekte können denselben Hash-Code haben, auch wenn sie unterschiedlich sind, aber wenn verschiedene Objekte denselben Hash-Code haben, muss "Equals" den Wert false zurückgeben.) –