9

モデルをフェッチした後にレンダリング関数が呼び出されていることをテストするために、バックボーン ビューのテストを作成しています。テストは次のとおりです。

beforeEach(function () {
    $('body').append('<div class="sidebar"></div>');
    profileView = new ProfileView();
});

it('should call the render function after the model has been fetched', function (done) {
    profileView.model = new UserModel({md5: 'd7263f0d14d66c349016c5eabd4d2b8c'});
    var spy = sinon.spy(profileView, 'render');
    profileView.model.fetch({
        success: function () {
            sinon.assert.called(spy);
            done();
        }
    });   
});

Sinon Spies を使用して、スパイ オブジェクトを profileView ビュー オブジェクトのレンダリング関数にアタッチしています。

ビューは次のとおりです。

var ProfileView = Backbone.View.extend({
    el: '.sidebar'
  , template: Hogan.compile(ProfileTemplate)
  , model: new UserModel()
  , initialize: function () {
        this.model.bind('change', this.render, this);
        this.model.fetch();
    }
  , render: function () {
        $(this.el).html(this.template.render());
        console.log("Profile Rendered");
        return this;
    }
});

テストで fetch が呼び出された後、change イベントが発生し、ビューの render 関数が呼び出されますが、Sinon Spy は render が呼び出されていることを検出せず、失敗します。

実験として、テストで render 関数を呼び出して、Spy がそれを識別したかどうかを確認してみました。

it('should call the render function after the model has been fetched', function (done) {
    profileView.model = new UserModel({md5: 'd7263f0d14d66c349016c5eabd4d2b8c'});
    var spy = sinon.spy(profileView, 'render');
    profileView.render();
    profileView.model.fetch({
        success: function () {
            sinon.assert.called(spy);
            done();
        }
    });   
});

スパイは、上記の場合にコールが行われたことを検出しました。

私の最初のテストで Spy がレンダリング呼び出しを識別しない理由を誰か知っていますか?

4

3 に答える 3

25

問題は、ビューの構築中に、初期化関数がイベントをレンダリング関数に直接バインドすることです。このイベントをスパイでインターセプトすることはできません。これは、スパイをセットアップする (構築後に行う) 前にバインドが既に行われているためです。

解決策は、ビューを構築する前にプロトタイプをスパイすることです。そのため、スパイを beforeEach に移動するか、ビューの構築をテストに移動する必要があります。

スパイをセットアップするには:

this.renderSpy = sinon.spy(ProfileView.prototype, 'render');
this.view = new ProfileView();

その後、スパイを削除するには:

ProfileView.prototype.render.restore()

これにより、レンダリングの「通常の」呼び出しと、モデルからの変更イベントがスパイされます。

于 2012-04-24T16:10:48.207 に答える
3

たった3つの推測:

  1. が更新され、Model イベントがトリガーされfetch({ success })た後にコールバックが呼び出されていると想定していますが、そうではない可能性があります。解決策:ここでデバッグを試してみくださいModel
  2. 呼び出しfetch成功しない可能性があるため、成功のコールバックは呼び出されません。解決策: にエラー コールバックを追加して、fetch送信先があるかどうかを確認してください。
  3. Model.validate応答、実装していない場合、可能性falseあまり高くありません。

(私は2に賭けます。 )

于 2012-03-14T14:27:00.800 に答える
0

スパイはコレクションで使用されていますが、これは私にとってはうまくいきました:

var thatzzz = this;
    this.hcns.fetch({
        success: function(){
            expect( thatzzz.hcnsFetchSpy ).toHaveBeenCalled();
        }
});
  • スパイはbeforeEachで定義されました
于 2012-03-28T16:17:45.403 に答える