Überprüfen der Objektgleichheit in Jasmine

84

Jasmine hat eingebaute Matcher toBeund toEqual. Wenn ich ein Objekt wie dieses habe:

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

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

und versuchen Sie zu vergleichen new Money(200, "USD")und das Ergebnis der Summe, diese eingebauten Matcher werden nicht wie erwartet funktionieren. Ich habe es geschafft, eine Problemumgehung basierend auf einer benutzerdefinierten equalsMethode und einem benutzerdefinierten Matcher zu implementieren , aber es scheint einfach zu viel Arbeit zu sein.

Was ist die Standardmethode zum Vergleichen von Objekten in Jasmine?

Dan
quelle

Antworten:

172

Ich suchte nach der gleichen Sache und fand einen bestehenden Weg, dies ohne benutzerdefinierten Code oder Matcher zu tun. Verwenden Sie toEqual().

lukas.pukenis
quelle
62

Wenn Sie Teilobjekte vergleichen möchten, sollten Sie Folgendes berücksichtigen:

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

obfk
quelle
3

Dies 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 Ihren eigenen Matcher schreiben, der vergleicht amountund currency:

beforeEach(function() {
  this.addMatchers({
    sameAmountOfMoney: function(expected) {
      return this.actual.currency == expected.currency && this.actual.amount == expected.amount;
    }
  });
});
Andreas Köberle
quelle
2

Ich fand, dass lodash _.isEqual gut dafür ist

expect(_.isEqual(result, expectedResult)).toBeTruthy()
Alexander Poshtaruk
quelle
-4

Ihr Problem ist die Wahrhaftigkeit. Sie versuchen, zwei verschiedene Instanzen eines Objekts zu vergleichen, die für die reguläre Gleichheit (a == b), aber nicht für die strikte Gleichheit (a === b) gelten. Der von Jasmin verwendete Komparator ist jasmine.Env.equals_ (), der nach strikter Gleichheit sucht.

Um das zu erreichen, was Sie benötigen, ohne Ihren Code zu ändern, können Sie die reguläre Gleichheit verwenden, indem Sie mit etwas wie dem folgenden auf Wahrhaftigkeit prüfen:

expect(money1.sum() == money2.sum()).toBeTruthy();
Baer
quelle
9
Was Sie gesagt haben ==und ===völlig falsch ist. Zwei verschiedene Instanzen eines Objekts mit demselben Inhalt geben beide false zurück. Für alle Nicht-Primitiven ==und ===verhalten sich identisch. jsfiddle.net/9mrmyrs6
Juan Mendes
@ JuanMendes schau dir die Antwort von Andreas K. an ... ihr sagt zwei verschiedene Dinge. Ist dies ein Unterschied zwischen der Neuerstellung eines Objekts und einem Objektliteral?
Pherris
@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 zur Behebung dieses Problems ist "richtig", aber die Erklärung im ersten Absatz ist einfach falsch. jasminewird tatsächlich den Objektinhalt überprüfen, wenn Sie toBe()anstelle vonequals
Juan Mendes
a == bwird immer noch falsch geben, wenn aund bsind verschiedene Instanzen, möchten Sie vielleicht Ihre Antwort bearbeiten
Louie Almeda