0

Jasmine を使用してビュー イベントをテストしようとしていますが、問題はおそらくコードで説明するのが一番です。

ビューは次のようになります。

App.testView = Backbone.View.extend({
  events: { 'click .overlay': 'myEvent' },
  myEvent: function(e) {
    console.log('hello world')
  }

テストは次のようになります。

describe('myEvent', function() {
  it('should do something', function() {
    var view = new App.testView();
    view.myEvent();
    // assertion will follow
  });
});

問題は、view.myEvent メソッドが呼び出されないことです (コンソールに何も記録されません)。DOM からのトリガーを回避しようとしていました。誰かが同様の問題を抱えていましたか?

4

1 に答える 1

5

(質問でコメントしたように、あなたのコードは問題なく動作するはずです。あなたの問題は、投稿したコードにはありません。コード サンプルを拡張して詳細情報を提供していただければ、もう一度検討することができます。以下は詳細です。バックボーン ビューのテストに関する一般的なアドバイス)。

あなたのようにイベント ハンドラー関数を呼び出すことは正当なテスト戦略ですが、いくつかの欠点があります。

  1. イベントが正しく接続されているかどうかはテストしません。テストしているのは、コールバックが想定どおりに機能することですが、ユーザーがページを操作したときにアクションが実際にトリガーされることはテストしていません。
  2. イベント ハンドラーがevent引数を参照する必要がある場合、またはテストは機能しません。

イベントからずっと自分のビューをテストすることを好みます。

var view = new View().render();
view.$('.overlay').click();

expect(...).toEqual(...);

あなたが言ったように、通常、テストで DOM を操作することはお勧めできません。そのため、ビューをテストするこの方法ではview.render、DOM に何も添付しない必要があります。

これを実現する最善の方法は、ビューの初期化を担当するコードに DOM 操作を任せることです。elビューにプロパティを設定しない場合(View.extend定義またはビュー コンストラクターのいずれかで)、Backbone は新しい切り離された DOM ノードを として作成しますview.el。この要素は、アタッチされたノードと同じように機能します。その内容を操作して、イベントをトリガーできます。

代わりに...

View.extend({el: '#container'});

...また...

new View({el:'#container'});

...次のようにビューを初期化する必要があります。

var view = new View();
$("#container").html(view.render().el);

このようにビューを定義すると、複数の利点があります。

  1. DOM にアタッチせずにビューを完全にテストできるようにします。
  2. ビューは再利用可能になり、複数のインスタンスを作成して、それらを異なる要素にレンダリングできます。
  3. renderメソッドが複雑な DOM 操作を行う場合は、切り離されたノードで実行する方が高速です。
  4. 責任の観点からは、モデルがどのコレクションに追加されるべきかを認識してはならないのと同じように、ビューはどこに配置されているかを認識すべきではないと主張することができます。これにより、ビュー構成のより良い設計が強制されます。

IMHO、このビュー レンダリング パターンは、単なるテスト関連の特別なケースではなく、一般的なベスト プラクティスです。

于 2013-01-09T13:06:23.080 に答える