1

私は RequireJS と Jasmine の両方にかなり慣れていないので、最初にいくつかの基本的なテストをセットアップするのに少し苦労しています。2つを一緒にセットアップして機能させる方法に関する多くの情報を見つけました。しかし、私には解決できない興味深い問題があります。

残念ながら、問題を表現する最善の方法がわからないので、ここにいくつかのコードを示します。

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

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

(余分なコードを削除しました)

console.logが中にいる場合Manipulate.pushChange、それは発砲しています。問題は、スパイされているオブジェクトが、ファイルManipulateで引数として渡されるオブジェクトと同じではないことです。main.jsしたがってmanipulate.pushChangeit()ブロックを追加すると、テストに合格します。

を呼び出す Backbone.js アプリの回答が見つかりましたdelegateEvents。バニラ Javascript、jQuery などに同様のソリューションがあるかどうかはわかりませんが、見つかりません。

私のファイルを構造化するより良い方法はありますか? それとも、2 つのオブジェクト間でイベントを「コピー」する方法ですか? createSpyこの場合、使用が私を大いに助けるとさえ信じていません。

4

1 に答える 1

2

コードには、テストを非常に困難にする問題がいくつかあります。まず、依存関係をモックしたい場合は、試したように requiereJs モジュールをテストすることはできません。いくつかの解決策については、このSOをご覧ください。

もう 1 つの問題は、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

コードがイベントをバインドすると、スパイが呼び出され、イベントが正しくバインドされたかどうかを確認できます。

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 に答える