我目前正在开发一个移动应用程序,我决定使用JQuery Mobile实现。但是,由于它将是一个官方应用程序,因此需要我对其进行测试,因此我决定使用我在学校学会处理的Jasmine。
目前我有一个客户端和服务器端,它使用 AJAX ($.getJSON
) 请求进行通信。
当其中一个 AJAX 请求被转发到其callback
方法时,它将调用一个 Notification
类来实现一个包含通知的div
。
我目前的问题是,当我使用以下代码时,它似乎总是在工作:
window.setTimeout(function () {
var expectedResult = "error";
var result = $("#test .ui-content .contentContainer .notification").text();
expect(result).toEqual(expectedResult);
}, 4000);
然而,几天后,我开始了一个新模块,并编辑了这些值,它继续工作,这将是非常错误的,因为它的旧的 - 不存在 - 代码。
所以我注意到这个单元测试实际上从未奏效。
所以我开始寻找替代方法并找到了runs
和waitsFor
功能,但我似乎无法让它们工作。
所以这里有一个测试:
it('should display an error when trying to add a new contact', function () {
runs(function () {
var contact = new Contact();
contact.addContact();
});
waitsFor(function () {
expect($("#test .ui-content .contentContainer .notification")).toBeVisible();
}, 5000);
var expectedResult = "asdf";
var result = $("#test .ui-content .contentContainer .notification").text();
expect(result).toEqual(expectedResult);
});
回调方法:
this.addContact_callback = function (data) {
$('#createContactForm')[0].reset();
$('.ui-dialog').dialog('close');
window.setTimeout(function () {
(new Contact()).retrieveContactList();
(new NotificationBox()).show(data.message[0], data.message[1]);
}, 250)
};
我的通知:
function NotificationBox() {
this.show = function (message, type) {
var activePage = $("body .ui-page-active").attr("id");
var create = "<div class='notification " + type + "'>" + message + "</div>";
$("#" + activePage + " .ui-content .contentContainer .notification").remove();
$("#" + activePage + " .ui-content .contentContainer").prepend(
$(create).hide().fadeIn('slow').delay(2500).fadeOut('slow', function () {
$(this).remove();
})
);
};
}
我希望有人能够为我提供解决这个主要问题的方法。
你的真诚,拉尔西1
您误用了waitsFor
方法。如果您阅读了官方文档,waitsFor
需要返回一个值,该值指示等待时间是否已结束。
您可能想执行以下操作:
waitsFor(function () {
return $("#test .ui-content .contentContainer .notification").is(":visible");
}, 5000);
您还缺少测试最后一部分的运行块。
runs(function () {
var expectedResult = "asdf";
var result = $("#test .ui-content .contentContainer .notification").text();
expect(result).toEqual(expectedResult);
});
尽管它可能不被视为解决方案,但它确实创建了更好的可管理和可测试的代码。
在我给定的代码示例中,我将代码转发到外部回调方法,就像我在给定的代码中使用addContact_callback
一样。跟踪实际结果的唯一方法是确定 notification
元素类的文本是什么。
话虽如此,很明显,如果您遇到此问题,您可能编写了脏代码。
出于这个原因,我将我的代码更改为更好的代码,它使用内部回调方法。这意味着代码看起来像这样:
function handleSomething () {
this.retrieveSomething(function (data) {
console.log(data);
});
}
function retrieveSomething (callback) {
$.ajax({
type: "GET",
url: "127.0.0.1/my.php",
success: function (data, status, xhr) {
return callback($.parseJSON(data);
}
});
}
这样可以确保我的代码更容易测试,因为我可以为单元测试实现自定义回调函数。
还记得旧的单元测试吗? 嗯,这是从:
window.setTimeout(function () {
var expectedResult = "error";
var result = $("#test .ui-content .contentContainer .notification").text();
expect(result).toEqual(expectedResult);
}, 4000);
自:
var contact = new Contact();
contact.retrieveSomething(function (data) {
var expectedResult = (new Contact()).errorMessages[4];
expect(data.message).toBe(expectedResult);
});
结论:确保始终可以测试返回输出,而不是简单地将其移动到 UI,然后尝试测试结果是否与预期相同。