测试Jasmine中自定义事件的处理

joe*_*tch 6 javascript unit-testing jasmine twitter-flight

我想确保在触发自定义jQuery事件时将对象的方法作为事件处理程序调用; 但单元测试似乎正在返回假阴性,因为我的实现工作得很好.

(这是使用Twitter FlightFlight Jasmine扩展的测试套件的一部分,但这只是一个香草茉莉花间谍.)

describe('listening for uiNeedsPlan event', function() {

var spy;
beforeEach(function() {
  spy = spyOn(this.component, 'getPlan');
  $(document).trigger('uiNeedsPlan');
});

it('gets the current plan', function() {
  expect(spy).toHaveBeenCalled();
});

});
Run Code Online (Sandbox Code Playgroud)

这会导致规范失败:

Expected spy getPlan to have been called.

这是我的Flight组件的代码实现的一个片段(它成功运行):

this.after('initialize', function () {
  this.on(document, 'uiNeedsPlan', this.getPlan);
});
Run Code Online (Sandbox Code Playgroud)

Tom*_*ere 12

在我详细说明为什么这不起作用之前,我首先要指出测试此方法是否已执行是不好的做法.您应该测试组件的接口 - 它的输入和输出及其对DOM的影响.它是如何做的(它调用哪些内部方法,它的内部状态)是无关紧要的.

至于为什么它不起作用:当您创建间谍时,您正在监视组件方法的未绑定版本.实例化组件时,方法绑定到实例并分配给回调.在实例化组件之后,不可能(afaik)访问这些绑定方法.

相反,您需要在组件实例附加到DOM之前监视原型.此外,您似乎根本没有调用setupComponent,因此无论如何this.component都不会存在.

var spy;

beforeEach(function () {
    spy = spyOn(this.Component, 'getPlan');
    setupComponent();
    $(document).trigger('uiNeedsPlan');
});
it('executes getPlan', function() {
    expect(spy).toHaveBeenCalled();
});
Run Code Online (Sandbox Code Playgroud)

  • 我完全同意.我说你应该测试组件的接口:输入和输出,而不是内部执行的过程.这是衡量一些事情做什么以及它是如何做的区别.将组件视为黑盒子.这样,当您更改内部工作时,您不必更改测试. (3认同)