1

私の JS ビューコードでは、jQuery UI Dialogコンポーネントを使用してポップアップをレンダリングしています。

次のようにインスタンス化します。

var popupDialog = $("#myPopupDiv").dialog({
    title: "My dialog",
    dialogClass: "myDialogClass",
    create: createHandler,
    draggable: false,
    width: width,
    height: height,
    autoOpen: false
});

autoOpen が「false」に設定されていることに注意してください。「作成」ハンドラーで開きます。

var createHandler = function(event, ui) {
    //Vi venter litt for å sikre at popupen er "klar"
    setTimeout(function () {
        popupDialog.dialog("open");
    }, 5);
};

setTimeoutポップアップの準備が整っていることを確認するために、open-logic は でラップされます。

コードはブラウザのアプリで正常に動作しますが、 Jasmine テスト フレームワークを使用してこのコードを実行すると、エラーが発生します。

エラー: 初期化前にダイアログでメソッドを呼び出すことはできません。メソッド「open」を呼び出そうとしました

テストは実際にパスするので、明らかにアイテムがレンダリングされます。しかし、テストを実行したときにエラーが表示されるのは好きではありません!

Jasmine テストが非常に高速に実行されるため、コンポーネントが初期化する時間がなかったのではないかと思います。では、コンポーネントが初期化されていることを確認するにはどうすればよいでしょうか? このロジックを「作成」ハンドラーに入れると、そのイベントは「ダイアログが作成されたときにトリガーされる」ので、それを処理できると思いましたが、明らかにそうではありません。

これが私がそれをテストする方法です:

it("should show my popup", function () {

    var myPopupLink = $('.popupLink');

    myPopupLink.click();

    //Wait until popup is shown
    waitsFor(function () {
        return !$('.myDialogClass').is(":hidden");
    }, "Popupen didn't show", 1000);

    //Check that the DOM is as expected
    expect($('.myDialogClass .popupContentDiv')).toExist();
    expect(...

    //Close popup
    myPopupLink.click();
    expect($('.myDialogClass .popupContentDiv')).not.toExist();

});

ポップアップダイアログの初期化ステータスを確認する方法を知っている人はいますか? または他の回避策はありますか?

ありがとう!

4

1 に答える 1

2

あなたのテストの問題は、単体テストよりも受け入れテストの方が多いということです。テストしようとするもののほとんどは、jQueryUi の機能です。本当にテストしたいのはcreateHandler、ダイアログが遅れて開いたことです。したがってpopupDialog.dialog、遅延後に呼び出されたことを確認できるスパイになる必要があります。

現時点では、コードは jquery に直接基づいているため、テストが非常に困難です。のようなグローバル変数に依存する代わりに、依存関係を注入できる関数を用意することを検討する必要がありますpopupDialog

すべての依存関係をモックアウトする方法の例を次に示します。

//mock out setTimeout so you dont have to wait in your test
jasmine.Clock.useMock();

//create a mock that will return from $().dialog()
var mockDialog = jasmine.createSpy('dialog');
// mock $ to return {dialog: mock that return {dialog: mockDialog}}
var mock$ = spyOn(window, '$').andReturn({
  dialog:jasmine.createSpy('$').andReturn({
    dialog: mockDialog
  })
})

expect(mock$).toHaveBeenCalled();

// call the create function    
window[mock$.mostRecentCall.args[0].create]();

jasmine.Clock.tick(4999);
expect(mockDialog$).not.toHaveBeenCalled();
jasmine.Clock.tick(5001);
expect(mockDialog$).toHaveBeenCalledWith('open');

ご覧のとおり、すべての jQuery 依存関係をモックアウトするのは非常に複雑です。したがって、テスト容易性を高めるためにコードを書き直すか、セレンカピバラなどを使用した受け入れテストとしてこれをテストします。

于 2013-01-20T11:54:40.340 に答える