Mocha+Chai+Sinon 学习笔记 (四)—— 测试异步代码的正确姿势

· 约 7 分钟读完

Mocha+Chai+Sinon 学习笔记 (四)—— 测试异步代码的正确姿势

在前端开发中,异步代码的使用十分常见,例如 Ajax 的请求、setTimeout 和 setInterval 的定时器、Promise 的异步操作等,这些异步操作给前端测试带来了一定难度。本篇文章将为大家介绍如何使用 Mocha、Chai 和 Sinon 库来测试异步代码,帮助大家掌握测试异步代码的正确姿势。

前置知识

在开始学习测试异步代码之前,我们需要先了解一些前置知识。

异步代码

异步代码是指不会立即返回结果的代码,而是在未来某个时间返回结果。例如,Ajax 请求就是异步代码,因为它需要等待服务器响应才能返回数据。异步代码执行时,程序无法继续向下执行,而是需要等待异步代码执行完毕后才能继续执行下一步操作。

测试框架

测试框架是指用于方便地编写、运行和管理测试用例的工具。 Mocha 是一款流行的 JavaScript 测试框架,它支持测试异步代码、浏览器和 Node.js 等多种环境。

断言库

断言库是指用于编写测试用例中的断言(即期望值与实际值的对比)的工具。 Chai 是一个流行的 JavaScript 断言库,它提供了多种 API 来检查变量的值,例如断言是否相等、是否为假值等。

模拟库

模拟库是指用于模拟函数、对象等行为的工具。 Sinon 是一个流行的 JavaScript 模拟库,它支持模拟函数的返回值、参数和函数执行情况等。

测试异步代码的正确姿势

在我们开始测试异步代码之前,需要清楚地明白一个问题:JavaScript 是单线程的,即任何时刻只能有一条指令被执行。因此,当 JavaScript 执行异步代码时,它不能像同步代码一样等待异步代码执行完毕再返回结果,而需要使用回调函数、Promise、async/await 等方式来处理异步操作。

在测试异步代码时,我们需要等待异步代码执行完毕后再进行断言。由于异步代码的执行时间是无法确定的,因此我们需要使用测试框架提供的一些特殊功能来处理异步操作。

Mocha 的异步支持

Mocha 提供了多种方式来支持测试异步代码,例如:

done()

done() 函数是 Mocha 提供的一种用于测试异步代码的方式。当一个测试用例使用 done() 函数时,Mocha 将等待 done() 函数被调用后再结束测试用例。例如:

在上述例子中,我们使用 getUserData 函数异步获取用户数据,并在回调函数中进行断言,然后调用 done() 函数告诉 Mocha 这个测试用例已经完成。

Promise

Mocha 支持测试 Promise 的异步代码,只需将返回 Promise 的函数返回值传递给 it() 函数即可。例如:

在上述例子中,我们使用 getUserData 函数异步获取用户数据,并在 then() 中进行断言,然后将 Promise 返回值传递给 it() 函数告诉 Mocha 这个测试用例已经完成。

async/await

Mocha 还支持测试 async/await 的异步代码,只需在测试函数前加上 async 关键字并使用 await 关键字即可。例如:

在上述例子中,我们使用 getUserData 函数异步获取用户数据,并在 await 后进行断言,然后使用 async 关键字告诉 Mocha 这个测试用例是异步的。

Sinon 的异步支持

Sinon 提供了多种方式来支持测试异步代码,例如:

clock

clock 是 Sinon 提供的用于测试定时器的工具。当我们需要测试定时器相关的异步代码时,可以使用 clock 来模拟时间流逝。例如:

在上述例子中,我们使用 setTimeout 异步调用 callback 函数,并使用 sinon.clock.tick() 函数将时间向前推进 1 秒钟。然后断言 callback 函数是否被调用一次。

stub

stub 是 Sinon 提供的用于模拟函数的工具。当我们需要测试异步代码中函数的行为时,可以使用 stub 来模拟函数的返回值、参数和执行情况等。例如:

在上述例子中,我们使用 sinon.stub() 函数模拟 api.getData() 函数,并设置其返回值为 { name: 'John' }。然后测试 getUserData 函数是否正确地调用了 api.getData() 函数,并传递了正确的参数。

示例代码

下面是一个完整的测试异步代码的示例代码。该示例中,我们模拟了一个异步请求,使用 Mocha、Chai 和 Sinon 库来测试异步请求是否正确地返回了指定数据。

在上述示例代码中,我们使用 sinon.fakeServer.create() 函数模拟了一个 HTTP 服务器,并使用 server.respondWith() 函数设置服务器响应内容为指定数据。然后使用 ajax() 函数发起异步请求,并在回调函数中进行断言。最后使用 server.restore() 函数来还原服务器状态。当 done() 函数被调用时,测试用例结束。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d6b3a7a941bf7134c8a255