准备条件
以第1节教程的创建的目录和代码为基础进行讲解。如果没有看过第1节教程,请关注我,查看以往该系列的文章
这节教程主要讲解在jest中怎样去测试异步代码,将第1节的代码复制一份,并且把index.js
和index.test.js
文件内容全部清空
在实际开发中,肯定会用到异步请求,请求后台的接口数据,这里我们就使用axios
来请求数据
npm install axios --save
安装axios- 在
index.js
中引入axios
import axios from 'axios'
在 index.js
中写异步代码
这里我们将一般请求的数据的写法都写进来
import axios from 'axios'
/**
* 传入一个回调函数,获取数据后执行
*/
export function featchData1(fn) {
// 实际开发应为接口路径
axios.get('https://bird.ioliu.cn/v2/?url=https://music.163.com/store/api/searchsuggest/get')
.then(response => {
fn(response.data)
})
}
/**
* 返回一个promise
*/
export function featchData2() {
// 实际开发应为接口路径
return axios.get('https://bird.ioliu.cn/v2/?url=https://music.163.com/store/api/searchsuggest/get')
}
/**
* 返回一个403接口
*/
export function featchData3() {
return axios.get('https://m10.music.126.net/20200114152235/1231231')
}
按照正常的逻辑去测试异步代码
import { featchData1, featchData2, featchData3 } from './index'
//错误示例
test('测试 featchData1', () => {
featchData1((data) => {
//测试data中是否包含code: 200
expect(data).toMatchObject({
code: 200
})
})
})
//错误示例
test('测试 fetchData2', () => {
featchData2().then(res => {
//测试data中是否包含code: 200
expect(res.data).toMatchObject({
code: 200
})
})
})
你会发现测试用例全部通过,貌似没有问题。但是你修改一下断言,不管怎样测试用例都是会通过,因为测试部分根本就没有执行。测试用例并不会等到你的请求结束后再去执行测试,因此我们并不能按照正常的逻辑去测试异步代码,正确写法请看下面
在index.test.js
中重新写正确的测试用例
这里我介绍4种不同的测试方法,大家不用纠结该用哪一个,自己喜欢哪个用哪个就好了
import { featchData1, featchData2, featchData3 } from './index'
/**
* 第一种:使用 done 方法
* 当你使用done时,测试用例会一直等到执行到done()方法才结束
*/
test('测试 1-featchData1', (done) => {
featchData1((data) => {
expect(data).toMatchObject({
code: 200
})
done()
})
})
test('测试 1-featchData2', (done) => {
featchData2().then(res => {
expect(res.data).toMatchObject({
code: 200
})
done()
})
})
test('测试 1-featchData3', (done) => {
featchData3().catch(e => {
expect(e.toString()).toEqual('Error: Request failed with status code 403')
done()
})
})
/**
* 第二种:如果返回的是一个 Promise 对象,可以直接使用 return 写法
*/
test('测试 2-featchData2', () => {
return featchData2().then(res => {
expect(res.data).toMatchObject({
code: 200
})
})
})
test('测试 2-featchData3', () => {
// 这里如果请求成功的话就不会走catch了,但是测试依旧会通过
// 因此需要加上下面一句,指定必须只能执行一次expect
expect.assertions(1)
return featchData3().catch(e => {
expect(e.toString()).toEqual('Error: Request failed with status code 403')
})
})
/**
* 第三种:如果返回的是一个 Promise 对象,可以直接使用 return + resolves/rejects 写法
* .resolves和.rejects 可以将promise的值返回,方便直接链式调用匹配器
*/
test('测试 3-featchData2', () => {
return expect(featchData2()).resolves.toMatchObject({
data: {
code: 200
}
})
})
test('测试 3-featchData3', () => {
return expect(featchData3()).rejects.toThrow()
})
/**
* 第四种:如果返回的是一个 Promise 对象,async + await
*/
test('测试 4-featchData2', async() => {
const results = await featchData2()
expect(results.data).toMatchObject({
code: 200
})
})
test('测试 4-featchData3', async () => {
expect.assertions(1)
try {
await featchData3()
} catch (error) {
expect(error.toString()).toEqual('Error: Request failed with status code 403')
}
})
以上代码都亲测没有问题,这节很重要,学习的小伙伴一定要自己动手练习一下,以便加深印象。也不用纠结实际开发中到底使用哪一个,选择自己最熟悉最擅长的即可
下一节教程将介绍在jest中的钩子函数以及钩子函数的作用域
大家加油!!!
本人能力有限,文章可能会有不正确或者不恰当的部分,希望你可以指出