Vérification de l'égalité des objets dans Jasmine


85

Jasmine a des matchers intégrés toBeet toEqual. Si j'ai un objet comme celui-ci:

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

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

et essayez de comparer new Money(200, "USD")et le résultat de la somme, ces matchers intégrés ne fonctionneront pas comme prévu. J'ai réussi à implémenter une solution de contournement basée sur une equalsméthode personnalisée et un matcher personnalisé, mais cela semble juste beaucoup de travail.

Quelle est la manière standard de comparer des objets dans Jasmine?

Réponses:


172

Je cherchais la même chose et j'ai trouvé un moyen existant de le faire sans aucun code personnalisé ni correspondance. Utilisez toEqual().


63

Si vous cherchez à comparer des objets partiels, vous pouvez envisager:

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

cf. jasmine.github.io/partial-matching


3

C'est le comportement attendu, car deux instances d'un objet ne sont pas les mêmes en 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

Pour un test propre, vous devez écrire votre propre matcher qui compare amountet currency:

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

2

J'ai trouvé que lodash _.isEqual est bon pour ça

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

-4

Votre problème est avec la vérité. Vous essayez de comparer deux instances différentes d'un objet qui est vrai pour l'égalité régulière (a == b) mais pas vrai pour l'égalité stricte (a === b). Le comparateur utilisé par jasmine est jasmine.Env.equals_ () qui recherche une égalité stricte.

Pour accomplir ce dont vous avez besoin sans changer votre code, vous pouvez utiliser l'égalité régulière en vérifiant la véracité avec quelque chose d'un peu comme ce qui suit:

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

9
Ce que vous avez dit ==et ===est complètement faux. Deux instances différentes d'un objet avec le même contenu renverront toutes deux false. Pour tous les non-primitifs, ==et ===se comportent de la même manière. jsfiddle.net/9mrmyrs6
Juan Mendes

@JuanMendes regarde la réponse d'Andreas K. ... vous dites deux choses différentes. Est-ce une différence dans la création d'un objet par rapport à un objet littéral?
pherris

@pherris mmm .... oui, nous disons des choses différentes: je dis que lorsque vous comparez des non-primitifs, peu importe que vous utilisiez ==ou ===, il n'y a pas de coercition. Andreas dit que vous pouvez créer un matcher personnalisé. La dernière déclaration sur la façon de résoudre ce problème est "correcte" mais l'explication dans le premier paragraphe est tout simplement incorrecte. jasminevérifiera réellement le contenu de l'objet si vous utilisez à la toBe()place deequals
Juan Mendes

a == bdonnera toujours false si aet bsont des instances différentes, vous voudrez peut-être modifier votre réponse
Louie Almeda
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.