通过使用“RequireJS”和“Jasmine”来监视一个名为“change”的函数。

时间:2022-08-23 11:41:30

I'm rather new at both RequireJS and Jasmine so I'm having a little trouble setting up a few basic tests to start with. I've found a lot of info on how to set up the two together, and have it working. However I have an interesting problem I can't seem to fix.

我对《RequireJS》和《茉莉花》都很陌生,所以我在开始一些基本的测试时遇到了一些麻烦。我找到了很多关于如何将两者结合起来的信息,并让它发挥作用。然而,我有一个有趣的问题,我似乎无法解决。

Unfortunately I'm not sure the best way to word the problem so here's some code:

不幸的是,我不确定这个问题的最好方法,所以这里有一些代码:

main.js:

main.js:

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

manipulate.js:

manipulate.js:

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

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

  return Manipulate;
});

ManipulateSpec.js:

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

(Removed some extra code)

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

If I console.log inside Manipulate.pushChange, it is firing. The problem is, the Manipulate object that is being spied on isn't the same object that is passed as an argument in the main.js file. So adding manipulate.pushChange in my it() block makes the test pass.

如果我控制台。日志内操作。pushChange,射击。问题是,被监视的操作对象与在main中作为参数传递的对象不相同。js文件。所以添加操作。我的it()块的pushChange使测试通过。

I found an answer for Backbone.js apps, which calls delegateEvents. I'm not sure if there is a similar solution for vanilla Javascript, jQuery, etc. but I can't find one.

我找到了一个解决问题的办法。js应用程序,它调用委托事件。我不确定是否有一个类似的解决方案,对于香草Javascript, jQuery等,但我找不到。

Is there a better way to structure my files, potentially putting my jQuery event handlers in the manipulate module? Or just a way to "copy" events between the two objects? I don't even believe using createSpy will help me much in this case.

是否有更好的方法来构造我的文件,可能将jQuery事件处理程序放在操作模块中?或者仅仅是“复制”两个对象之间的事件?我甚至不相信使用createSpy会对我有很大帮助。

1 个解决方案

#1


2  

There are some problems with your code that make it really hard to test. First you can't test requiereJs modules like the way you try it, if you wanna mock the dependencies. Take a look at this SO for some solutions.

您的代码存在一些问题,使得测试非常困难。首先,如果您想要模拟依赖项,您不能测试requiereJs模块,比如您尝试它的方式。让我们来看看这个问题。

The other problem is that you relay on jquery and DOM events. So most of the time I doesnt try to rebuild the DOM with fixtures for the test. Instead I spy on the jquery object that the event was binded to and call the function by myself. So in for your code

另一个问题是,您将在jquery和DOM事件上进行传递。因此,大多数时候,我并没有试图用测试装置来重建DOM。相反,我监视着jquery对象,该对象被绑定到并由我自己调用该函数。这是你的代码。

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

you could spy on $like this

你可以像这样监视美元。

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

Now when your code bind the event it will just call the spy and you can check if the event was binded correctly:

当代码绑定事件时,它会调用spy,你可以检查事件是否被正确地绑定:

var callback = documentSpy.on.mostRecentCall.args[2]
expect(documentSpy.on).toHasBeenCalledWith('change', 'td input', callback);
// fire the callback
callback();
expect(manipulate.pushChange).toHaveBeenCalled();

#1


2  

There are some problems with your code that make it really hard to test. First you can't test requiereJs modules like the way you try it, if you wanna mock the dependencies. Take a look at this SO for some solutions.

您的代码存在一些问题,使得测试非常困难。首先,如果您想要模拟依赖项,您不能测试requiereJs模块,比如您尝试它的方式。让我们来看看这个问题。

The other problem is that you relay on jquery and DOM events. So most of the time I doesnt try to rebuild the DOM with fixtures for the test. Instead I spy on the jquery object that the event was binded to and call the function by myself. So in for your code

另一个问题是,您将在jquery和DOM事件上进行传递。因此,大多数时候,我并没有试图用测试装置来重建DOM。相反,我监视着jquery对象,该对象被绑定到并由我自己调用该函数。这是你的代码。

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

you could spy on $like this

你可以像这样监视美元。

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

Now when your code bind the event it will just call the spy and you can check if the event was binded correctly:

当代码绑定事件时,它会调用spy,你可以检查事件是否被正确地绑定:

var callback = documentSpy.on.mostRecentCall.args[2]
expect(documentSpy.on).toHasBeenCalledWith('change', 'td input', callback);
// fire the callback
callback();
expect(manipulate.pushChange).toHaveBeenCalled();