2013-05-06 13 views
66

Jasmine hat integrierte Matcher toBe und toEqual. Wenn ich ein Objekt wie diese:Überprüfung der Objektgleichheit in Jasmine

function Money(amount, currency){ 
    this.amount = amount; 
    this.currency = currency; 

    this.sum = function (money){ 
     return new Money(200, "USD"); 
    } 
} 

und versuche new Money(200, "USD") und das Ergebnis der Summe zu vergleichen, dieser Einbau-Matcher wird nicht wie erwartet funktionieren. Ich habe es geschafft, ein Work-Around basierend auf einem benutzerdefinierten equals method und benutzerdefinierten Matcher zu implementieren, aber es scheint nur zu viel Arbeit.

Was ist der Standard Weg, um Objekte in Jasmine zu vergleichen?

Antwort

131

Ich war auf der Suche für die gleiche Sache und fand einen bestehenden Weg ohne benutzerdefinierten Code oder Matcher. Verwenden Sie toEqual().

3

Es ist das erwartete Verhalten, da zwei Instanzen eines Objekts in JavaScript nicht identisch sind.

function Money(amount, currency){ 
    this.amount = amount; 
    this.currency = currency; 

    this.sum = function (money){ 
    return new Money(200, "USD"); 
    } 
} 

var a = new Money(200, "USD") 
var b = a.sum(); 

console.log(a == b) //false 
console.log(a === b) //false 

Für einen sauberen Test sollten Sie Ihre eigenen Matcher schreiben, die amount und currency vergleicht:

beforeEach(function() { 
    this.addMatchers({ 
    sameAmountOfMoney: function(expected) { 
     return this.actual.currency == expected.currency && this.actual.amount == expected.amount; 
    } 
    }); 
}); 
-1

Ihr Problem mit truthyness ist. Sie versuchen, zwei verschiedene Instanzen eines Objekts zu vergleichen, die für die reguläre Gleichheit (a == b) wahr sind, aber nicht für die strikte Gleichheit (a === b). Der Komparator, den Jasmin verwendet, ist jasmine.Env.equals_(), die für strenge Gleichheit sucht.

Um das zu erreichen, was Sie brauchen, ohne den Code ändern Sie die regelmäßige Gleichheit durch Überprüfung für truthyness mit etwas ein wenig wie die folgende verwenden:

expect(money1.sum() == money2.sum()).toBeTruthy(); 
+7

Was Sie über '==' und '===' gesagt haben, ist völlig falsch. Zwei verschiedene Instanzen eines Objekts mit demselben Inhalt geben beide Falsch zurück. Für alle Nicht-Primitiven verhalten sich '==' und '===' identisch. http://jsfiddle.net/9mrmyrs6/ –

+0

@JuanMendes überprüfen Sie die Antwort von Andreas K. ... Sie sagen zwei verschiedene Dinge. Ist das ein Unterschied, wenn Sie ein Objekt gegen ein Objektliteral neu erstellen? – pherris

+0

@pherris mmm ... ja, wir sagen verschiedene Dinge: Ich sage, dass es beim Vergleich von Nicht-Primitiven egal ist, ob Sie '==' oder '===' verwenden, es gibt keinen Zwang . Andreas sagt, dass Sie einen benutzerdefinierten Matcher erstellen können. Die letzte Aussage, wie man dieses Problem beheben kann, ist "korrekt", aber die Erklärung im ersten Absatz ist nur falsch. 'Jasmine' überprüft tatsächlich den Inhalt des Objekts, wenn Sie' toBe() 'anstelle von' equals' verwenden. –

38

Wenn Sie schauen, Teilobjekte zu vergleichen, sollten Sie überlegen:

describe("jasmine.objectContaining", function() { 
    var foo; 

    beforeEach(function() { 
    foo = { 
     a: 1, 
     b: 2, 
     bar: "baz" 
    }; 
    }); 

    it("matches objects with the expect key/value pairs", function() { 
    expect(foo).toEqual(jasmine.objectContaining({ 
     bar: "baz" 
    })); 
    }); 
}); 

vgl jasmine.github.io/partial-matching

+0

Dies sollte die richtige Antwort sein – chaotive