Jasmine:测试toHaveBeenCalledWith(params),其中params是一个对象

时间:2014-02-22 21:00:51

标签: javascript testing jasmine

我正在使用Jasmine进行一些测试,在寻找间谍的预期参数时会产生奇怪的结果。

我正在测试使用toHaveBeenCalledWith()方法并寻找类似这样的东西:

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

它会失败,但错误消息似乎确认实际上找到了完全相同的对象。

可能出现这种情况的原因是什么?

2 个答案:

答案 0 :(得分:5)

等效函数定义不相等。所以,

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

使用toHaveBeenCalledWith()时,你必须引用相同的函数定义,以便Jasmine认为它等于传递给spied对象方法的参数。您是否可以将新的对象定义(如您在问题中包含的对象)传递给toHaveBeenCalledWith()?这不会通过Jasmine断言。

这是我运行的Jasmine规范,说明了我所说的内容。有一个成功的例子和一个失败的例子:

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

答案 1 :(得分:0)

可能的解决方案是使用:自定义非对称相等性测试器。让测试人员决定如何确定平等。 示例:

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 comparison method you wish to use)
  }
};

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

});

希望这会有所帮助。