Javascript 监视jQuery调用的函数';改变';带着安魂曲和茉莉花

Javascript 监视jQuery调用的函数';改变';带着安魂曲和茉莉花,javascript,jquery,requirejs,jasmine,jasmine-jquery,Javascript,Jquery,Requirejs,Jasmine,Jasmine Jquery,我对RequireJS和Jasmine都是新手,所以我在开始设置一些基本测试时遇到了一些问题。我已经找到了很多关于如何将两者结合在一起的信息,并使其发挥作用。然而,我有一个有趣的问题,我似乎无法解决 不幸的是,我不确定解决问题的最佳方法,因此这里有一些代码: main.js: require(['jquery', 'manipulate'], function($, Manipulate) { var manipulate = new Manipulate; $(document).on

我对RequireJS和Jasmine都是新手,所以我在开始设置一些基本测试时遇到了一些问题。我已经找到了很多关于如何将两者结合在一起的信息,并使其发挥作用。然而,我有一个有趣的问题,我似乎无法解决

不幸的是,我不确定解决问题的最佳方法,因此这里有一些代码:

main.js:

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

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

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

  return Manipulate;
});
expndtw-1.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();
  });
});
(删除了一些额外的代码)

如果I
console.log
operate.pushChange
内,则它正在启动。问题是,被监视的
operate
对象与在
main.js
文件中作为参数传递的对象不同。因此,在my
it()
块中添加
Operation.pushChange
会使测试通过

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


是否有更好的方法来构造文件,将jQuery事件处理程序潜在地放在操纵模块中?或者只是在两个对象之间“复制”事件的一种方法?我甚至不相信在这种情况下使用
createSpy
会对我有多大帮助。

您的代码存在一些问题,这使得测试非常困难。首先,如果您想模拟依赖项,就不能像您尝试的那样测试requirerejs模块。看看这个,可以找到一些解决方案

另一个问题是依赖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();

我想你部分回答了你自己的问题。您没有对当前正在测试的
operate
实例执行操作。我看到了两种不同的方法来解决这个问题:1)考虑“<代码>操作< /代码>是否是一个“静态”对象,而不是一个“经典”对象的原型。实例化
操纵
会给你买什么吗?e、 g.-
var-operate={pushChange:function(){return true;}}2)找出一种将实际被测对象注入jQuery事件处理程序的好方法。我还要补充一点,我不确定
主干。这里的View#delegateEvents
是完全一致的。在主干网中,您可以调用
this.delegateEvents
,手动连接视图的
events
散列中声明的所有事件。此外,jQuery是主干的可选依赖项。因此,如果主干网看到
$
jQuery
,那么它将使用jQuery的API在视图中连接DOM事件,而不是通过其他方式。我知道这并没有真正解决你问题的根源,只是关于主干如何工作的额外花絮而已。:)我最初编写它是为了有一个“构造函数”,以便在那里定义我的事件侦听器(忘记将它从main.js移到那里)。我去掉了它,使它成为一个对象,带有一个
initialize
函数,我可以在需要附加事件时调用它。很有意思。我已经研究过了,但到目前为止还没有什么理由这么做。我最后用了你大部分的答案,但我没能让这些模拟起作用。因此,我没有使用
createSpy
来监视
.on()
调用,而是直接监视
$.fn.on
。但除此之外,要测试的其余代码工作得非常出色。谢谢你的帮助!我的最后一个完整测试:啊,很高兴知道它将以这种方式工作。谢谢你的发现。