10

互いに副作用を引き起こしている 2 つのテストがあります。2 番目のテストで内部的に呼び出されている jQuery 組み込み関数を置き換えている理由がわかりました。しかし、私が理解していないのは、テストが交互に成功したり失敗したりする理由です。

この質問は似ていますが、qunit-fixture div で直接何もしていません。

ここに私のテストがあります

test('always passing test', function() { // Always passes
    var panelId = '#PanelMyTab';

    var event = {};
    var ui = {
        tab: {
            name: 'MyTab',
        },
        panel: panelId,
    };

    $('<div id="' + panelId + '">')
        .append('<a href="#" class="export">Test</a>')
        .append('<a href="#" class="showForm">Show Form</a>')
        .appendTo('#qunit-fixture');

    jQuery.fn.on = function(event, callback) {
        ok(this.selector == panelId + ' .export', 'Setting export click event');
        equal(callback, tickets.search.getReport, 'Callback being set');
    };

    loadTab(event, ui);
});

test('alternately passing and failing', function() { // Alternates between passing and failing on page refresh
    expect(5);

    var testUrl = 'test';
    $('<div class="ui-tabs-panel">')
        .append('<a href="'+ testUrl + '" id="getReport">Get Report</a>')
        .append('<form action="notest" target="" class="ticketSearch"></form>')
        .appendTo('#qunit-fixture');

    // Setup form mocking
    $('form.ticketSearch').submit(function() {
        var urlPattern = new RegExp(testUrl + '$');
        ok(urlPattern.test($(this).prop('action')), 'Form action set to link href');
        equal($(this).prop('target'), '_blank', 'Open form on a new page');
    });

    var event = {
        target: 'a#getReport',
    };

    var result = getReport(event);

    var form = $('form.ticketSearch');

    ok(/notest$/.test($(form).prop('action')), 'Making sure action is not replaced');
    equal($(form).prop('target'), '', 'Making sure that target is not replaced');

    ok(false === result, 'click event returns false to not refresh page');
});

テストは合格から始まりますが、更新すると、合格と不合格が交互に繰り返されます。

なぜこうなった?URL に GET パラメーターを追加しても、ページ上で同じ動作が発生します。

失敗するケースでは、ハンドラーが設定されている.on()ときに内部 jQuery が呼び出しているため、テストが失敗しています。submit()しかし、その場合、テストが常に失敗しないのはなぜですか? ページの更新中に状態が保持されているブラウザは何をしていますか?

アップデート:

テスト中のコードは次のとおりです。

var tickets = function() {
    var self = {
        loadTab: function(event, ui) {
            $(panel).find('.export').button().on('click', this.getReport);
        },

        search: {
            getReport: function(event) {
                var button = event.target;
                var form = $(button).closest('div.ui-tabs-panel').find('form.ticketSearch').clone(true);

                $(form).prop('action', $(button).prop('href'));
                $(form).prop('target', '_blank');

                $(form).submit();

                return false;
            }
        }
    };

    return self;
}();
4

2 に答える 2

0

もう少し情報がないとこれを解決できるかどうかはわかりませんが、考えられる問題をいくつか指摘できます。

最初のテストの 2 行目に無効な構文があるようです

var panelId = '#PanelMyTab');

しかし、それはおそらく型の間違いです。あなたが言うように、最初のものは常に通過します。

最初のテストが合格する (そして有効になる) ためには、loadTab(event,ui) が jQuery.fn.on() を実行する必要があると想定していますが、アサーションは実行されていません。jQuery UIタブでいくつかのテストを行っているのは、そのようです(それがあなたの意図であるかどうかはわかりません)。

これらのアサーションをその関数内に置くことが賢明かどうかはわかりません.jquery関数を何もしない関数で上書きしたため、問題が発生する可能性があることを理解する必要があります.

2 番目のテストでも同様のことを行っているようですが、5 つのアサーションが期待されていますが、最後の 3 つがどのように実行されるかしかわかりません。

ok(/notest$/.test($(form).prop('action')), 'Making sure action is not replaced');
equal($(form).prop('target'), '', 'Making sure that target is not replaced');
ok(false === result, 'click event returns false to not refresh page');

他の 2 つは、テストの一部として呼び出されたようには見えない送信関数内にあります。

これらのテストは同期的であるため、テストを実行して失敗する前に送信を待つことはありません。

ここに例があります

test('asynchronous test', function() {
    setTimeout(function() {
        ok(true);
    }, 100)
})

テストの 100 ミリ秒後に ok が実行されるため、失敗します。

test('asynchronous test', function() {
    // Pause the test first
    stop();

    setTimeout(function() {
        ok(true);

        // After the assertion has been called,
        // continue the test
        start();
    }, 100)
})

stop() は qunit に待機するように指示し、start() は開始するように指示します!

ここの API で詳述されている asyncTest() もあります

最後に、これらのテストでコードをデバッグしようとしているようです。Chrome 開発者ツールまたは firefox の firebug を使用してコードにブレークポイントを設定し、console.log() および console.dir() を使用して情報を出力する方がはるかに簡単です。

そうは言っても、それがどのように機能するのかまったくわからないので、何かが欠けている可能性があります:)それでも行き詰まっている場合は、周囲のコードをさらに追加できるかどうか、および何を達成しようとしているのかを確認してください. お役に立てれば。

PS:};あなたが私たちに与えたコードでは無効な最後にもありますが、実際のアプリケーションではおそらく関連があります ;)

于 2013-06-02T23:07:58.060 に答える