gpt4 book ai didi

javascript - 使用 QUnit 对 AJAX 请求进行单元测试

转载 作者:数据小太阳 更新时间:2023-10-29 05:04:37 27 4
gpt4 key购买 nike

我们正在尝试为 JS 密集型 Web 应用程序实现 QUnit JavaScript 测试。我们正在努力寻找一种方法来成功测试涉及 jQuery AJAX 请求的方法。例如,我们有下面的构造函数(显然这是一个非常简单的例子):

var X = function() {
this.fire = function() {
$.ajax("someURL.php", {
data: {
userId: "james"
},
dataType: "json",
success: function(data) {
//Do stuff
}
});
};
};
var myX = new X();
myX.fire();

我们正在尝试找到一种方法来测试 fire 方法,最好使用 stub URL 而不是真正的 someURL.php

目前对我来说唯一明显的解决方案是添加 URL 和 success 回调,作为构造函数的参数。这样,在测试中,我们可以创建一个新的 X 实例并传入 stub URL,以及在 stub 返回响应时运行的回调。例如:

test("Test AJAX function", function() {
stop();
var myX = new X();
//Call the AJAX function, passing in the stub URL and success callback
myX.fire("stub.php", function(data) {
console.log(data);
start();
});
});

但是,这似乎不是一个很好的解决方案。有没有更好的办法?

最佳答案

使用 jQuery,您可以使用 .ajax() 返回的 xhr 对象作为 promise ,因此您可以添加更多处理程序(见下文),而不仅仅是单个 successcompleteerror 您在选项中定义的。因此,如果您的异步函数可以返回 xhr 对象,您可以添加特定于测试的处理程序。

至于 URL,这有点棘手。我有时会在本地主机上设置一个非常简单的节点服务器,它只提供从真实服务器复制的固定响应。如果您在同一台服务器上运行您的测试套件,您的 URL 只需要是访问测试服务器而不是生产服务器的绝对路径。而且您还会获得请求本身的记录,就像服务器看到的那样。或者,如果您想查看代码如何处理它,您可以让测试服务器故意发回错误或错误响应。

但这当然是一个相当复杂的解决方案。更简单的方法是在可以从测试套件重新定义它们的地方定义您的 URL。例如:

/* in your code */
var X = function () {
this.fire = function () {
return $.ajax({ url: this.constructor.url, ... });
};
};
X.url = "someURL.php"; // the production url

/* in your tests */
X.url = "stub.php"; // redefine to the test url

另外,QUnit 有一个asyncTest 函数,它会为您调用stop()。添加一个小助手来跟踪何时重新开始,您就得到了一个非常好的解决方案。

这是我之前做过的

// create a function that counts down to `start()`
function createAsyncCounter(count) {
count = count || 1; // count defaults to 1
return function () { --count || start(); };
}

// ....

// an async test that expects 2 assertions
asyncTest("testing something asynchronous", 2, function() {
var countDown = createAsyncCounter(1), // the number of async calls in this test
x = new X;

// A `done` callback is the same as adding a `success` handler
// in the ajax options. It's called after the "real" success handler.
// I'm assuming here, that `fire()` returns the xhr object
x.fire().done(function(data, status, jqXHR) {
ok(data.ok);
equal(data.value, "foobar");
}).always(countDown); // call `countDown` regardless of success/error
});

基本上 countDown 是一个函数,它从您指定的任何内容开始倒数到零,然后调用 start()。在本例中,有 1 个异步调用,因此 countDown 将从中开始倒计时。当 ajax 调用完成时,它会执行此操作,无论它如何进行,因为它被设置为 always 回调。
因为 asyncTest 被告知需要 2 个断言,所以如果从未调用 .done() 回调,它将报告错误,因为不会运行任何断言。因此,如果调用完全失败,您也会知道。如果您想记录错误,您可以向 promise 链添加一个 .fail() 回调。

关于javascript - 使用 QUnit 对 AJAX 请求进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9431597/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com