我有一个模式登录视图,我正在用 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();
});
一些简短的理由:我将绝大多数视图作为独立组件进行处理,然后在称为区域(以 Marionette 为模型)的自定义视图变体中呈现 - 我通常发现这是一个很好的整洁实践,可以帮助我跟踪什么位于应用程序中的位置,与给定“空间”中的内容分开。此策略似乎不适用于诸如此类的花哨模式,因此渲染发生在隐藏的现有 DOM 元素中,然后移动到该区域中,因此需要将代码附加 'popupLoginWrapper' 到测试区域.
如果我直接使用空事件参数调用登录方法,上述相同的测试也会失败。Jasmine 给了我以下错误“错误:预期是间谍,但得到了功能。” (这是有道理的,因为它调用的是 redirectToOrigin 的实际实现而不是 spy。
我有类似的测试通过了,问题似乎与 params.success() 的触发有关,但这是测试所必需的。
附加:禁用测试后,我发现此问题会影响此模式的大多数测试。通过单步执行,我可以看到在某些情况下应用了 spy 并执行了 spy 代码,但随后似乎触发了真正的成功调用。