Comprobando la igualdad de objetos en Jasmine

85

Jasmine tiene emparejadores incorporados toBey toEqual. Si tengo un objeto como este:

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

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

e intente comparar new Money(200, "USD")y el resultado de la suma, estos comparadores integrados no funcionarán como se esperaba. Me las arreglé para implementar una solución alternativa basada en un equalsmétodo personalizado y un comparador personalizado, pero parece que funciona mucho.

¿Cuál es la forma estándar de comparar objetos en Jasmine?

Dan
fuente

Respuestas:

172

Estaba buscando lo mismo y encontré una forma existente de hacerlo sin ningún código personalizado o comparadores. Utilice toEqual().

lukas.pukenis
fuente
63

Si está buscando comparar objetos parciales, podría considerar:

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

obfk
fuente
3

Es el comportamiento esperado, ya que dos instancias de un objeto no son iguales 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

Para una prueba limpia, debe escribir su propio comparador que compare amounty currency:

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

Encontré que lodash _.isEqual es bueno para eso

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

Tu problema es la veracidad. Está tratando de comparar dos instancias diferentes de un objeto que es verdadero para la igualdad regular (a == b) pero no es cierto para la igualdad estricta (a === b). El comparador que usa jasmine es jasmine.Env.equals_ () que busca igualdad estricta.

Para lograr lo que necesita sin cambiar su código, puede usar la igualdad regular verificando la veracidad con algo parecido a lo siguiente:

expect(money1.sum() == money2.sum()).toBeTruthy();
Baer
fuente
9
Lo que dijiste ==y ===está completamente equivocado. Dos instancias diferentes de un objeto con el mismo contenido devolverán falso. Para cualquier no primitivo ==y se ===comporta de manera idéntica. jsfiddle.net/9mrmyrs6
Juan Mendes
@JuanMendes mira la respuesta de Andreas K. ... ustedes están diciendo dos cosas diferentes. ¿Es esta una diferencia entre la renovación de un objeto y un objeto literal?
pherris
@pherris mmm .... sí, estamos diciendo cosas diferentes: estoy diciendo que al comparar no primitivos, no importa si usas ==o ===, no hay coerción involucrada. Andreas dice que puedes crear un comparador personalizado. La última declaración sobre cómo solucionar este problema es "correcta", pero la explicación en el primer párrafo es simplemente incorrecta. jasminecomprobará el contenido del objeto si lo usa en toBe()lugar deequals
Juan Mendes
a == bseguirá dando falso si ay bson instancias diferentes, es posible que desee editar su respuesta
Louie Almeda