最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Jasmine: Testing toHaveBeenCalledWith(params) where params is an object - Stack Overflow

programmeradmin3浏览0评论

I'm doing some testing with Jasmine, having a strange result when looking for expected params as a result of a Spy.

I'm testing using the toHaveBeenCalledWith() method and looking for something like this:

{
  foo: bar,
  thing: [1,2,3],
  etc: function() { blah; }
}

It gives a fail, but the error message seems to confirm the exact same object is actually being found.

Any reasons why this might be the case?

I'm doing some testing with Jasmine, having a strange result when looking for expected params as a result of a Spy.

I'm testing using the toHaveBeenCalledWith() method and looking for something like this:

{
  foo: bar,
  thing: [1,2,3],
  etc: function() { blah; }
}

It gives a fail, but the error message seems to confirm the exact same object is actually being found.

Any reasons why this might be the case?

Share Improve this question asked Feb 22, 2014 at 21:00 Don HDon H 9012 gold badges15 silver badges24 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 9

Equivalent function definitions are not equal. So,

function() { return 'blah'; } == function() { return 'blah'; } // returns false

You have to reference the same function definition when using toHaveBeenCalledWith() for Jasmine to consider it equal to the argument passed to the spied object's method. Are you maybe passing in a new object definition (like the object you included in your question) to toHaveBeenCalledWith()? That will not pass the Jasmine assertion.

Here is the Jasmine spec I ran which illustrates what I said. There is a succeeding example and a failing example:

describe("A spy example", function() {
    var baz  = {
        foo: 'bar',
        thing: [1,2,3],
        etc: function() { }
    };

    beforeEach(function() {
        spyOn(baz, 'etc');
        baz.etc(baz);
    });

    it("succeeds", function() {
        expect(baz.etc).toHaveBeenCalledWith(baz);
    });

    it("fails", function() {
        expect(baz.etc).toHaveBeenCalledWith({
            foo: 'bar',
            thing: [1,2,3],
            etc: function() { }
        });
    });
});

A possible solution is to use: Custom asymmetric equality tester. Which let's the tester decide how to determine equality. Example:

describe("A spy example", function() {

var baz  = {
    foo: 'bar',
    thing: [1,2,3],
    etc: function() { }
};

beforeEach(function() {
    spyOn(baz, 'etc');
    baz.etc(baz);
});

it("succeeds", function() {
    expect(baz.etc).toHaveBeenCalledWith(baz);
});

var customTester = {
  asymmetricMatch: function(actual) {
    return actual.foo === 'bar' && 
           actual.thing.length === 3 // && ... ( any deep parison method you wish to use)
  }
};

it("succeeds too", function() {
    expect(baz.etc).toHaveBeenCalledWith(customTester);
});

});

Hope this helps.

发布评论

评论列表(0)

  1. 暂无评论