Checking object equality in Jasmine

JavascriptBddJasmineObject Comparison

Javascript Problem Overview


Jasmine has built-in matchers toBe and toEqual. If I have an object like this:

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

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

and try to compare new Money(200, "USD") and the result of sum, these built-in matchers will not work as expected. I have managed to implement a work-around based on a custom equals method and custom matcher, but it just seems to much work.

What is the standard way to compare objects in Jasmine?

Javascript Solutions


Solution 1 - Javascript

I was looking for the same thing and found an existing way to do so without any custom code or matchers. Use toEqual().

Solution 2 - Javascript

If you're looking to compare partial objects, you might consider:

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

Solution 3 - Javascript

Its the expected behavior, as two instances of an object are not the same in 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

For a clean test you should write your own matcher that compares amount and currency:

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

Solution 4 - Javascript

I found that lodash _.isEqual is good for that

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

Solution 5 - Javascript

I managed to compare two objects without any custom code via :

import { deepStrictEqual } from 'assert'
// ...
expect(deepStrictEqual.bind(null, objectA, objectB)).not.toThrow()

note : assert is a native node module, no need to install anything here

Solution 6 - Javascript

Your problem is with truthyness. You are trying to compare two different instances of an object which is true for regular equality ( a == b ) but not true for strict equality ( a === b). The comparator that jasmine uses is jasmine.Env.equals_() which looks for strict equality.

To accomplish what you need without changing your code you can use the regular equality by checking for truthyness with something a little like the following:

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDanView Question on Stackoverflow
Solution 1 - Javascriptlukas.pukenisView Answer on Stackoverflow
Solution 2 - JavascriptoriginalhatView Answer on Stackoverflow
Solution 3 - JavascriptAndreas KöberleView Answer on Stackoverflow
Solution 4 - JavascriptAlexander PoshtarukView Answer on Stackoverflow
Solution 5 - JavascriptSsh-uunenView Answer on Stackoverflow
Solution 6 - JavascriptBaerView Answer on Stackoverflow