1

我对 RequireJS 和 Jasmine 都很陌生,所以我在设置一些基本测试时遇到了一些麻烦。我找到了很多关于如何将两者设置在一起并使其正常工作的信息。但是我有一个有趣的问题,我似乎无法解决。

不幸的是,我不确定解决问题的最佳方式,所以这里有一些代码:

主.js:

require(['jquery', 'manipulate'], function($, Manipulate) {
  var manipulate = new Manipulate;
  $(document).on('change', 'td input', function() {
    manipulate.pushChange();
  });
});

操纵.js:

define(function() {
  function Manipulate() {
    //
  };

  Manipulate.prototype.pushChange = function() {
    return true;
  };

  return Manipulate;
});

操纵规范.js:

describe('Manipulate', function() {
  var manipulate;

  beforeEach(function() {
    var flag = false;

    // Load fixtures into the HTML
    loadFixtures('ManipulateFixture.html');

    // Require the manipulate.js file
    require(['jquery', 'manipulate', 'main'], function(jQuery, Manipulate) {
      manipulate = new Manipulate;

      // Define any spies
      spyOn(manipulate, 'pushChange');

      flag = true;
    });

    // Wait for manipulate.js to load before running tests
    waitsFor(function() {
      return flag;
    });
  });

  it('should call pushChange after changing a cell', function() {
    $('td input').eq(0).trigger('change');
    expect(manipulate.pushChange).toHaveBeenCalled();
  });
});

(删除了一些额外的代码)

如果我console.log在里面Manipulate.pushChange,它正在开火。问题是,Manipulate被监视的对象与main.js文件中作为参数传递的对象不同。因此,添加manipulate.pushChange我的it()块使测试通过。

我找到了 Backbone.js 应用程序的答案,它调用delegateEvents. 我不确定香草 Javascript、jQuery 等是否有类似的解决方案,但我找不到。

有没有更好的方法来构建我的文件,可能将我的 jQuery 事件处理程序放在操作模块中?或者只是一种在两个对象之间“复制”事件的方法?createSpy在这种情况下,我什至不相信 using会对我有多大帮助。

4

1 回答 1

2

您的代码存在一些问题,使得测试变得非常困难。首先,如果你想模拟依赖项,你不能像你尝试它的方式那样测试 requiereJs 模块。看看这个SO以获得一些解决方案。

另一个问题是您在 jquery 和 DOM 事件上进行中继。所以大多数时候我不会尝试使用测试装置重建 DOM。相反,我监视事件绑定到的 jquery 对象并自己调用该函数。所以在你的代码中

$(document).on('change', 'td input', function() {
  manipulate.pushChange();
});

$你可以像这样监视

var documentSpy ={on:jasmine.createSpy()};
spyOn(window, "$").andReturn(event); // in a requireJs module mock it like in the SO I've mention above

现在,当您的代码绑定事件时,它只会调用 spy,您可以检查事件是否正确绑定:

var callback = documentSpy.on.mostRecentCall.args[2]
expect(documentSpy.on).toHasBeenCalledWith('change', 'td input', callback);
// fire the callback
callback();
expect(manipulate.pushChange).toHaveBeenCalled();
于 2013-01-30T13:41:11.327 回答