我有一个类,我在初始化时绑定一个方法,如下所示 -
function MyClass() {
this.onHttpCallback = _.bind(onHttpCallback, this);
}
function onHttpCallback(){
//...
}
如何测试调用onHttpCallback
时是否始终使用MyClass对象作为上下文调用?
我正在使用sinon.js进行模拟,以下代码不起作用 -
it('should be binded', function () {
//ctrl is an object of MyClass
var dummy_obj = {};
var spy = sinon.spy(ctrl.onHttpCallback);
spy.call(dummy_obj);
spy.alwaysCalledOn(ctrl).should.be.ok;
});
更新 根据以下答案中的注释,似乎无法测试方法的绑定。
我接受问题
//Source.js
function MyClass() {
}
MyClass.prototype.init = function(){
this.onHttpCallback = _.bind(MyClass.onHttpCallback, this);
}
MyClass.onHttpCallback(){
//...
}
//Test.js
it('should bind onHttpCallback', function () {
sinon.spy(_, 'bind');
ctrl.init();
_.bind.calledWith(ctrl.constructor.onHttpCallback, ctrl).should.be.ok;
_.bind.restore();
});
像魅力一样!
答案 0 :(得分:2)
如果您想知道为什么this
会发生变化,即使您之前明确将其绑定为MyClass
,那也是因为您在间谍上使用call
dummy_obj
。
间谍包装原始函数,因此它没有该函数绑定的概念。它仍将接受对包装函数的不同绑定,然后尝试使用this
调用原始函数,然后原始函数将其忽略。
var context = {foo: 'bar'};
var original = _.bind(function () { console.log(this); }, context);
var spy = function (original) {
var spyFn = function () {
var _this = this;
spyFn.calledOn = function (ctx) { return ctx === _this; };
return original.apply(this, arguments);
};
return spyFn;
};
var originalSpy = spy(original);
// Will call the spyFn with a different `this`, but will not affect the original binding
originalSpy.call({something: 'else'});
>> {foo: 'bar'}
// Since the spy cannot know the original binding, it will think the assumption is false.
originalSpy.calledOn(context) === false;