0

Jasmine でテストしているモーダル ログイン ビューがあります。ログインボタンがリダイレクトされることをテストする厄介な問題があります。モックして呼び出しをテストできるようにリダイレクトをメソッドに入れましたが、サインインボタンでクリックイベントをトリガーすると、スパイは無視されるようです。

これが私がテストしているビューです...

define(['ministry', 'models/m-auth', 'helpers/cookie-manager', 'text!templates/modals/login.html', 'jquery.custom'],
function (Ministry, Authentication, CookieManager, TemplateSource) {
    var loginView = Ministry.SimpleView.extend({

        name: 'Login',

        el: "#popupLoginWrapper",

        template: Handlebars.compile(TemplateSource),

        events: {
            'submit #loginForm': 'signIn'
        },

        redirectToOrigin: function () {
            // TODO: Change location to member home when implemented
            location.href = '/#/jqm';
        },

        signIn: function (e) {
            var that = this;

            e.preventDefault();

            // As we have no input yet log in manually using the auth model...
            var authData = new Authentication.Request({
                requestSource: $('#requestSource').text(),
                apiKey: $('#apiKey').text(),
                username: '*****',
                password: '*****'
            });

            // This saves the login details, generating a session if necessary, then creates a cookie that lasts for 1 hour
            authData.save(authData.attributes, {                    
                success: function () {
                    if (authData.generatedHash !== undefined && authData.generatedHash !== null && authData.generatedHash !== '')
                        CookieManager.CreateSession(authData.generatedHash);
                        that.redirectToOrigin();
                }
            });
        },
    });

    return loginView;
});

(現在、ハードコードされたアカウントでログインしています。実際のコントロールを配線するのが次の仕事です)。そして、これが問題のテストです(ここでは、簡単にするためにすべての前後をテストに結合しました)...

        var buildAndRenderView = function (viewObject) {
            viewObject.render();
            $('#jasmineSpecTestArea').append(viewObject.el);
            return viewObject;
        };

        it("signs in when the 'Sign In' button is clicked", function () {
            spyOn(objUt, 'redirectToOrigin').andCallFake(Helper.DoNothing);
            spyOn(Backbone.Model.prototype, 'save').andCallFake(function (attributes, params) {
                params.success();
            });

            $('body').append('<div id="jasmineSpecTestArea"></div>');
            $('#jasmineSpecTestArea').append('<section id="popupLoginWrapper"></section>');
            objUt = new View();
            buildAndRenderView(objUt);

            objUt.$('#loginForm button').click();

            expect(objUt.redirectToOrigin).toHaveBeenCalled();

            $('#jasmineSpecTestArea').remove();
        });

いくつかの簡単な理由: 私は自分のビューの大部分を独立したコンポーネントとして作成し、それを Region (Marionette をモデルにした) と呼ばれるカスタム ビュー バリアントでレンダリングします。特定の「スペース」に保持されているものとは別に、アプリ内のどこに座っています。この戦略は、このようなファンシーボックス モーダルでは機能しないようです。そのため、レンダリングは非表示の既存の DOM 要素で行われ、リージョンに移動されます。そのため、コードで「popupLoginWrapper」をテスト領域に追加する必要があります。 .

空のイベント引数でサインイン メソッドを直接呼び出すと、上記の同じテストも失敗します。Jasmine から次のエラーが表示されます。「エラー: スパイが必要ですが、関数を取得しました。」(スパイではなく、redirectToOrigin の実際の実装を呼び出しているため、これは理にかなっています。

同様のテストに合格しましたが、問題は params.success() のトリガーにあるようですが、これはテストに必要です。

追加: テストを無効にした後、この問題がこのモーダルのほとんどのテストに影響を与えていることがわかりました。ステップスルーすると、スパイが適用され、スパイコードが実行される場合があることがわかりますが、実際の成功の呼び出しはその後にトリガーされるようです。

4

1 に答える 1

0

私はこの問題を修正したようです - 厳密にはわかりません。数日後、完全に新鮮にアプローチしました-テストは次のようになります...

            var buildAndRenderView = function (viewObject) {
                viewObject.render();
                $('#jasmineSpecTestArea').append(viewObject.el);
                viewObject.postRender();
                return viewObject;
            };

               it("signs in when the 'Sign In' button is clicked", function () {
                    $('body').append('<div id="jasmineSpecTestArea"></div>');
                    $('#jasmineSpecTestArea').append('<section id="popupLoginWrapper"></section>');
                    objUt = new View();
                    spyOn(objUt, 'redirectToOrigin').andCallFake(Helper.DoNothing);
                    spyOn(objUt, 'displayError').andCallFake(Helper.DoNothing);
                    spyOn(Backbone.Model.prototype, 'save').andCallFake(function (attributes, params) {
                        params.success();
                    });

                    objUt = buildAndRenderView(objUt);
                    objUt.$('#loginForm button').click();

                    expect(objUt.redirectToOrigin).toHaveBeenCalled();
                    expect(objUt.displayError).not.toHaveBeenCalled();
                    $('#jasmineSpecTestArea').remove();
                });

最初の問題以降、エラー アラート メカニズムをラップしたため、displayError 呼び出しが追加されたため、特に関連性はありません。テストを修正した後、いくつかの変数セットを postRender に分割したので、これも関係ありません。

問題は、戻り値がオブジェクトに設定されずに buildAndRenderView メソッドを呼び出しているようでした。これを変えることで…

buildAndRenderView(objUt);

に...

objUt = buildAndRenderView(objUt);

問題は解決しました。

于 2013-08-14T09:13:14.870 に答える