【问题标题】:Test the context of a method call using sinonjs使用 sinonjs 测试方法调用的上下文
【发布时间】:2014-04-21 11:54:55
【问题描述】:

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

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

更新 根据以下答案中的 cmets,似乎无法测试方法的绑定。

我对这个问题的看法

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

像魅力一样工作!

【问题讨论】:

  • 您用dummy_obj 将间谍称为this,所以很明显this 不会是ctrl。我错过了什么吗?是你期望this在使用_.bind后无法更改的问题吗?
  • 你没问题。我基本上是想测试一下,不管我怎么调用onHttpCallback方法,上下文都应该是ctrl

标签: javascript unit-testing mocking sinon


【解决方案1】:

如果您想知道为什么 this 会发生变化,即使您之前明确将其绑定为 MyClass,那是因为您在间谍上使用了 calldummy_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;

【讨论】:

  • 这很有意义。 sinon默认没有实现吗?我的意思是,这不是一个常见的用例吗?
  • 这几乎是不可能的,因为bind 基本上是位于间谍之下一层的另一个包装器。您必须监视您正在绑定的功能。我认为这种测试是过度测试。您应该相信 underscore 对 _.bind 方法的测试正在通过,而不必自己再次检查它。更好地测试实际功能。更重要的是,onHttpCallback 函数对您传递的this 执行正确的操作。为此,您必须公开它,包括手动设置其 this 绑定的方法。
  • 我猜你是对的,现在我将离开它:(
  • 如果对你有帮助的话,如果你能接受这个答案就好了。
  • 您可以在github.com/cjohansen/Sinon.JS/blob/… 中看到它采用您调用函数spy 的this 值。内部发生的事情实际上无法判断函数是否已绑定。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-01-16
  • 2016-01-21
  • 1970-01-01
  • 2016-05-07
  • 1970-01-01
  • 2020-01-23
  • 1970-01-01
相关资源
最近更新 更多