Sprawdzanie równości obiektów w Jasmine

85

Jasmine ma wbudowane dopasowujące toBei toEqual. Jeśli mam taki obiekt:

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

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

i spróbuj porównać, new Money(200, "USD")a wynik sumy, te wbudowane dopasowania nie będą działać zgodnie z oczekiwaniami. Udało mi się zaimplementować obejście oparte na niestandardowej equalsmetodzie i niestandardowym dopasowywaniu, ale wydaje się, że wymaga to dużo pracy.

Jaki jest standardowy sposób porównywania obiektów w Jasmine?

Dan
źródło

Odpowiedzi:

172

Szukałem tego samego i znalazłem istniejący sposób na zrobienie tego bez żadnego niestandardowego kodu lub dopasowań. Użyj toEqual().

lukas.pukenis
źródło
63

Jeśli chcesz porównać częściowe obiekty, możesz rozważyć:

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

por. jasmine.github.io/partial-matching

obfk
źródło
3

Jest to oczekiwane zachowanie, ponieważ dwie instancje obiektu nie są takie same w JavaScript.

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

Aby uzyskać czysty test, powinieneś napisać własny matcher, który porównuje amounti currency:

beforeEach(function() {
  this.addMatchers({
    sameAmountOfMoney: function(expected) {
      return this.actual.currency == expected.currency && this.actual.amount == expected.amount;
    }
  });
});
Andreas Köberle
źródło
2

Odkryłem, że lodash _.isEqual jest do tego dobry

expect(_.isEqual(result, expectedResult)).toBeTruthy()
Alexander Poshtaruk
źródło
-4

Twoim problemem jest prawdomówność. Próbujesz porównać dwie różne instancje obiektu, który jest prawdziwy dla zwykłej równości (a == b), ale nie jest prawdziwy dla ścisłej równości (a === b). Porównawcą używanym przez jaśmin jest jaśmin.Env.equals_ (), który szuka ścisłej równości.

Aby osiągnąć to, czego potrzebujesz, bez zmiany kodu, możesz użyć zwykłej równości, sprawdzając prawdziwość za pomocą czegoś podobnego do następującego:

expect(money1.sum() == money2.sum()).toBeTruthy();
Baer
źródło
9
To, o czym powiedziałeś ==i ===jest całkowicie błędne. Dwa różne wystąpienia obiektu o tej samej zawartości zwrócą wartość false. Dla wszystkich nieprymitywów ==i ===zachowują się identycznie. jsfiddle.net/9mrmyrs6
Juan Mendes
@JuanMendes sprawdź odpowiedź Andreasa K. ... mówicie dwie różne rzeczy. Czy to różnica w tworzeniu nowego obiektu w porównaniu z literałem obiektu?
pherris
@pherris mmm .... tak, mówimy różne rzeczy: mówię, że porównując nieprymitywy, nie ma znaczenia, czy używasz, czy ==też ===nie ma przymusu. Andreas mówi, że możesz stworzyć niestandardowy dopasowywanie. Ostatnie stwierdzenie, jak rozwiązać ten problem, jest „poprawne”, ale wyjaśnienie w pierwszym akapicie jest po prostu niepoprawne. jasminefaktycznie sprawdzi zawartość obiektu, jeśli użyjesz toBe()zamiastequals
Juan Mendes,
a == bnadal będzie podawać wartość fałsz, jeśli ai bistnieją różne instancje, możesz zmienić swoją odpowiedź
Louie Almeda