Ü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?

Antworten:


172

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


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


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;
    }
  });
});

2

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

expect(_.isEqual(result, expectedResult)).toBeTruthy()

-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();

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.