我正在尝试使用 Jasmine 为基本的 jQuery AJAX 请求编写一些 BDD 规范。我目前在独立模式下使用 Jasmine(即通过 SpecRunner.html
)。我已将 SpecRunner 配置为加载 jquery 和其他 .js 文件。为什么以下不起作用的任何想法? has_returned 不会变为真,甚至认为“雅皮士!”警报显示正常。
describe("A jQuery ajax request should be able to fetch...", function() {
it("an XML file from the filesystem", function() {
$.ajax_get_xml_request = { has_returned : false };
// initiating the AJAX request
$.ajax({ type: "GET", url: "addressbook_files/addressbookxml.xml", dataType: "xml",
success: function(xml) { alert("yuppi!"); $.ajax_get_xml_request.has_returned = true; } });
// waiting for has_returned to become true (timeout: 3s)
waitsFor(function() { $.ajax_get_xml_request.has_returned; }, "the JQuery AJAX GET to return", 3000);
// TODO: other tests might check size of XML file, whether it is valid XML
expect($.ajax_get_xml_request.has_returned).toEqual(true);
});
});
如何测试回调是否已被调用?非常感谢任何指向与使用 Jasmine 测试异步 jQuery 相关的博客/ Material 的指针。
最佳答案
我猜你可以做两种类型的测试:
- 伪造 AJAX 请求的单元测试(使用 Jasmine 的 spy ),使您能够测试在 AJAX 请求之前和之后运行的所有代码。您甚至可以使用 Jasmine 伪造来自服务器的响应。这些测试会更快 - 而且它们不需要处理异步行为 - 因为没有任何真正的 AJAX 正在进行。
- 执行真实 AJAX 请求的集成测试。这些需要是异步的。
Jasmine 可以帮助您进行这两种测试。
下面是一个示例,说明如何伪造 AJAX 请求,然后编写单元测试来验证伪造的 AJAX 请求是否转到正确的 URL:
it("should make an AJAX request to the correct URL", function() {
spyOn($, "ajax");
getProduct(123);
expect($.ajax.mostRecentCall.args[0]["url"]).toEqual("/products/123");
});
function getProduct(id) {
$.ajax({
type: "GET",
url: "/products/" + id,
contentType: "application/json; charset=utf-8",
dataType: "json"
});
}
对于 Jasmine 2.0,请改用:
expect($.ajax.calls.mostRecent().args[0]["url"]).toEqual("/products/123");
如 this answer 中所述
这是一个类似的单元测试,用于在 AJAX 请求成功完成后验证您的回调是否已执行:
it("should execute the callback function on success", function () {
spyOn($, "ajax").andCallFake(function(options) {
options.success();
});
var callback = jasmine.createSpy();
getProduct(123, callback);
expect(callback).toHaveBeenCalled();
});
function getProduct(id, callback) {
$.ajax({
type: "GET",
url: "/products/" + id,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: callback
});
}
对于 Jasmine 2.0,请改用:
spyOn($, "ajax").and.callFake(function(options) {
如 this answer 中所述
最后,您在别处暗示您可能想要编写发出真正 AJAX 请求的集成测试 - 用于集成目的。这可以使用 Jasmine 的异步功能来完成:waits()、waitsFor() 和 runs():
it("should make a real AJAX request", function () {
var callback = jasmine.createSpy();
getProduct(123, callback);
waitsFor(function() {
return callback.callCount > 0;
});
runs(function() {
expect(callback).toHaveBeenCalled();
});
});
function getProduct(id, callback) {
$.ajax({
type: "GET",
url: "data.json",
contentType: "application/json; charset=utf-8"
dataType: "json",
success: callback
});
}
关于javascript - 如何使用 Jasmine 验证 jQuery AJAX 事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4662641/