準備條件
以第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中的鉤子函數以及鉤子函數的作用域
大家加油!!!
本人能力有限,文章可能會有不正確或者不恰當的部分,希望你可以指出