javascript - 使用 sinonjs 测试方法调用的上下文

标签 javascript unit-testing mocking sinon

我有一个类,在初始化时绑定(bind)一个方法,如下 -

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

更新 根据以下答案中的注释,似乎不可能测试方法的绑定(bind)。

我对问题的看法

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

工作起来就像一个魅力!

最佳答案

如果您想知道为什么 this 会发生变化,即使您之前明确将其绑定(bind)为 MyClass,那是因为您将 call 一起使用>dummy_obj 在 spy 上。
spy 包装了原始函数,因此它没有该函数绑定(bind)的概念。它仍然会接受包装函数上的不同绑定(bind),然后尝试使用该 this 调用原始函数,然后原始函数会忽略该绑定(bind)。

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;

关于javascript - 使用 sinonjs 测试方法调用的上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23196928/

相关文章:

android - 创建用于测试的模拟 Activity 的最快方法

java - 如何在基于代理的Spring bean中设置模拟对象?

javascript - 使用 Knockout 和复选框进行 ajax 调用时出现问题

javascript - Jquery滚动多个使li标签处于事件状态

c# - Rhino Mocks - stub 一个单例

unit-testing - 使用 BLoC 模式测试小部件

javascript - 显式设置 CouchDB 文档键

javascript - 带有 Bootstrap 输入复选框的 Angular ng-repeat 以及使用 ng-true-value 的动态 ng-model

unit-testing - 如何验证对用作委托(delegate)(委托(delegate))的参数进行的调用?

python - Luigi 参数默认值和模拟