Jasmine的间谍问题已经解决了原型方法问题

Tom*_*Doe 6 jquery prototype jasmine jasmine-jquery

我在一个方法上进行间谍活动的例子是失败,"已经调用了预期的间谍handle_click".什么时候应该通过.但是,我收到控制台日志"Foo handle_click called!",所以我知道它正在调用.

Foo.js

function Foo() {
    this.$btn = $('<a href="#">Foo</a>');
    this.$btn.on('click', this.handle_click);
};
Foo.prototype.handle_click = function(evt) {
    evt.preventDefault();
    console.log('Foo handle_click called!');
};
Run Code Online (Sandbox Code Playgroud)

Foo_spec.js:

it('should be called when trigger is clicked', function() {
    var foo = new Foo();
    spyOn( foo, 'handle_click' ).andCallThrough();
    foo.$btn.click();
    expect( foo.handle_click ).toHaveBeenCalled();
});
Run Code Online (Sandbox Code Playgroud)

我使用的是jasmine-1.2.0,jasmin-html和jasmine-jquery,但不是jasmine-sinon; 至少我不认为它捆绑在那里.任何帮助深表感谢!

更新 以下解答.但是,我想在jQuery插件的情况下记录解决方案:

Foo.js:

function Foo() { ... }
Foo.prototype.handle_click = function(evt) { ... }

$.fn.foo = function(options) {
    return new Foo(this, options || {});
};

$.fn.foo.prototype = Foo.prototype;
Run Code Online (Sandbox Code Playgroud)

Foo_spec.js:

it('should be called when clicked', function() {
    spyOn( $.fn.foo.prototype, 'handle_click');
    var plugin = $('#selector-for-plugin').foo();
    plugin.$btn.click();
    expect( plugin.handle_click ).toHaveBeenCalled();
});
Run Code Online (Sandbox Code Playgroud)

And*_*rle 2

问题是您handle_click在构造函数中绑定了该函数。因此,当您创建新实例时,对该函数的引用将绑定到事件。之后你foo.handle_click用间谍代替。但这不会影响绑定到事件的函数,因为这仍然是您的原始函数。您必须在创建实例之前监视Foo.prototype.handle_click函数,以便将监视的函数绑定到事件。

it('should be called when trigger is clicked', function() {
  spyOn( Foo.prototype, 'handle_click' );
  var foo = new Foo();
  foo.$btn.click();
  expect( foo.handle_click ).toHaveBeenCalled();
});
Run Code Online (Sandbox Code Playgroud)