Jasmine中done()方法如何使用?异步Web服务测试实操疑问
我懂这种对着文档抓瞎的感觉!Jasmine 2.x之后弃用了runs()/waitsFor(),改用done()确实更简洁,但刚上手的时候确实容易摸不清门路,尤其是文档里没怎么拿真实异步请求举例,难怪你会懵。下面我用大白话+实际代码给你讲透怎么用done()测试异步Web服务:
Jasmine 2.6中
done()测试异步Web服务的完整指南 一、先搞懂done()的核心逻辑
Jasmine默认是同步测试:代码从上到下跑完,立刻判断断言结果。但Web服务调用是异步的——你发请求后,代码会直接往下走,不会等接口返回。如果不用done(),测试会直接跳过异步逻辑,要么误判“通过”,要么拿到错误的结果。
done()的作用就是给Jasmine发信号:“我有个异步任务没做完,你先别判断结果,等我调用done()了再算!”,Jasmine会暂停测试,直到你手动触发这个信号,或者超时(默认5秒)就直接判失败。
二、完整的异步测试代码结构(拿真实Web服务举例)
假设你用fetch调用后端接口,我给你写个能直接套用的例子:
// 先定义一个调用Web服务的函数(你自己的业务代码) function fetchUserInfo(userId) { return fetch(`/api/users/${userId}`) .then(response => { if (!response.ok) throw new Error("请求失败"); return response.json(); }); } // Jasmine测试用例部分 describe("用户信息接口异步测试", () => { // 关键:给it函数传入done参数! it("应该正确获取指定用户的信息", (done) => { // 1. 执行异步操作:调用Web服务 fetchUserInfo(1001) .then(user => { // 2. 在这里写断言,验证返回结果是否符合预期 expect(user.id).toBe(1001); expect(user.nickname).toBe("小测试"); expect(user.isActive).toBe(true); // 3. 异步操作完成,调用done()告诉Jasmine:可以判断结果了 done(); }) .catch(error => { // 4. 如果请求失败,也要调用done(),把错误传进去,Jasmine会标记测试失败并显示错误信息 done(error); }); }); });
三、常见坑点和简化写法
- 必须传
done参数:如果it()里没写(done),Jasmine会当成同步测试,直接结束,根本不会等你的接口返回。 - 一定要调用
done():不管成功失败都要调用,不然测试会超时失败(Jasmine会一直等你发信号)。 - 用async/await更简洁:Jasmine 2.6已经支持
async/await,写法更像同步代码,Jasmine会自动处理done()的逻辑:it("用async/await简化异步测试", async () => { try { const user = await fetchUserInfo(1001); expect(user.id).toBe(1001); expect(user.nickname).toBe("小测试"); } catch (error) { // 用fail函数手动标记测试失败并输出错误 fail(`接口请求失败:${error.message}`); } }); - 自定义超时时间:如果你的接口响应慢,默认5秒不够,可以给
it()加第三个参数设置超时(单位毫秒):it("测试慢响应的接口", (done) => { fetchUserInfo(1001) .then(user => { expect(user.id).toBe(1001); done(); }) .catch(done); }, 10000); // 这里设置超时10秒
四、为什么文档里没真实异步调用?
官方文档常常用setTimeout模拟异步场景,本质和Web服务调用是一样的——都是需要等待的异步操作,比如:
it("用setTimeout模拟异步测试", (done) => { setTimeout(() => { expect(1 + 1).toBe(2); done(); }, 1000); });
你把setTimeout换成你的Web服务调用逻辑,用法完全一致。
内容的提问来源于stack exchange,提问作者Yimin Rong
相关产品推荐
相关产品推荐

