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