Checking object equality in Jasmine

2019-03-12 01:09发布

问题:

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?

回答1:

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



回答2:

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



回答3:

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


回答4:

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