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

Javascript 使用sinonjs测试方法调用的上下文,javascript,unit-testing,mocking,sinon,Javascript,Unit Testing,Mocking,Sinon,我有一个类,我在初始化时绑定一个方法,如下所示- function MyClass() { this.onHttpCallback = _.bind(onHttpCallback, this); } function onHttpCallback(){ //... } 如何测试调用onHttpCallback时,是否总是使用MyClass的对象作为上下文进行调用 我正在使用sinon.js进行模拟,但以下代码不起作用- it('should be binded', funct

我有一个类,我在初始化时绑定一个方法,如下所示-

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

工作起来很有魅力

如果您想知道,即使您之前明确将其绑定为
MyClass
,为什么
这个
会改变,那是因为您在间谍上使用
call
dummy\u obj

spy封装了原始函数,因此它没有该函数绑定的概念。它仍将接受包装函数上的不同绑定,然后尝试使用该
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;

你用
dummy\u obj
作为
this
调用间谍,因此显然
this
将不会是
ctrl
。我错过什么了吗?问题是您希望
在使用
后无法更改此
。我基本上想测试一下,无论我如何调用
onHttpCallback
方法,上下文都应该是
ctrl
,这很有意义。默认情况下,它不是在sinon中实现的吗?我的意思是,这不是一个常见的用例吗?这几乎是不可能的,因为
bind
基本上是另一个包装器,它位于间谍的下面一层。您必须监视正在绑定的函数。我认为这种测试太过分了。您应该相信下划线对
\uu.bind
方法的测试正在通过,而不必亲自检查。更好地测试实际功能。更重要的是,
onHttpCallback
函数对您要传递的
这个
进行正确的处理。为此,您必须公开它,包括手动设置此绑定的方法。我想您是对的,现在我将离开它:(如果答案对您有帮助的话,如果您能够接受,那就太好了。您可以看到,它采用了调用函数spy时使用的
这个
值。内部的情况实际上无法判断函数是否绑定。