我有以下的Jest测试,包括使用ajax调用模拟服务器XMLHttpRequest
:
import mock from "xhr-mock";
describe("ajax callbacks", function() {
beforeEach(function() {
mock.setup();
});
afterAll(function() {
mock.teardown();
});
it("gets called when done", function(done) {
mock.get("/get-url", {
status: 200,
body: '{ "key": "value" }'
});
const doneCallback = jest.fn();
const xhr = new XMLHttpRequest();
xhr.open("GET", "/get-url");
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE) {
doneCallback();
done();
}
}
xhr.send();
expect(doneCallback).toHaveBeenCalled();
});
});
这显然会失败,因为AJAX调用是异步处理的,并且在调用回调之前就已经产生了期望。
有什么办法可以让Jest等到回调被调用后再进行期望?
请注意,由于域要求,我无法将请求转换为同步请求。而且我也不能仅仅为了能够对其进行测试就将其转换为基于Promise的API。这只是正在编写的测试的简化版本,以便此处的人们可以轻松地掌握它。实际的代码是不同的,并且它对此处编写的内容具有抽象性。
我基本上通过使用async/await
Jest提供的支持来解决它。解决方案是将异步请求包装到中,Promise
并Promise
在onreadystatechange
调用回调时解决。因此:
import mock from "xhr-mock";
describe("ajax callbacks", function() {
beforeEach(function() {
mock.setup();
});
afterAll(function() {
mock.teardown();
});
it("gets called when done", async function() {
mock.get("/get-url", {
status: 200,
body: '{ "key": "value" }'
});
const doneCallback = jest.fn();
const xhr = new XMLHttpRequest();
xhr.open("GET", "/get-url");
await new Promise(function(resolve) {
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE) {
doneCallback();
resolve();
}
}
xhr.send();
});
expect(doneCallback).toHaveBeenCalled();
});
});
使用await
将使测试暂停直到Promise
解决。我知道这感觉有些棘手。但这就是我们目前所拥有的。我尝试寻找其他解决方案,但找不到任何解决方案。
要了解有关async/await
与Jest一起使用的更多信息,请参考此处。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句