用 axios 远程的请求数据。要使用 axios 就需要先进行安装,直接使用 npm 或 yarn 进行安装就可以了
npm install axios@0.19.0 --save |
安装完成后,可以打开 package.json
看一下安装结果和版本,我这里使用的是 0.19.0 (如果你是其它版本,可能这个方法会出错,所以你最好和我使用一样的版本)。
# 异步代码的测试方法 - 1
一个异步请求地址 http://a.jspang.com/jestTest.json
安装好 axios 以后,在项目根目录下面,新建一个文件 fetchData.js 文件,然后编写代码如下:
import axios from 'axios' | |
export const fetchData = (fn)=>{ | |
axios.get('http://a.jspang.com/jestTest.json').then((response)=>{ | |
fn(response.data) | |
}) | |
} |
测试文件 fetchData.test.js
在项目根目录下,新建一个 fetchData.test.js
文件
import { fetchData } from './fetchData.js' | |
test('fetchData 测试',()=>{ | |
fetchData((data)=>{ | |
expect(data).toEqual({ | |
success: true | |
}) | |
}) | |
}) |
注意这样写是由问题的,因为方法还没有等到回调,我们的结果已经完成了,所以这时候你对于没测试完,只是方法可用,就返回了测试结果,这种结果是不保证正确的。
比如现在我们把请求的地址后边加一个 1, 这时候才测试,依然是正确的。
axios.get('http://a.jspang.com/jestTest1.json').then((response)=>{ | |
fn(response.data) | |
}) |
所以我们必须加入一个 done
方法,保证我们的回调已经完成了,这时候我们表示测试完成。
import { fetchData } from './fetchData.js' | |
test('fetchData 测试',(done)=>{ | |
fetchData((data)=>{ | |
expect(data).toEqual({ | |
success: true | |
}) | |
done() | |
}) | |
}) |
# 异步代码的测试方法 - 2 直接返回 promise
还有一种方法式直接返回一个 promise 值,这样的方法在工作中也式经常使用的.
fetchData.js
文件,然后编写下面的代码:
export const fetchTwoData = ()=>{ | |
return axios.get('http://a.jspang.com/jestTest.json') | |
} |
从代码中可以看出,我们直接只用了 Return
返回了异步请求的 promise
值,这样的方法在实际工作中也经常使用。
打开 fetchData.test.js
文件,然后新写一个测试用例,在写之前记得先把 fetchTwoData
方法引过来。
import { fetchData , fetchTwoData } from './fetchData.js' |
引入之后,编写测试用例,代码如下:
test('FetchTwoData 测试', ()=>{ | |
return fetchTwoData().then((response)=>{ | |
expect(response.data).toEqual({ | |
success: true | |
}) | |
}) | |
}) |
这部分代码需要注意的是要使用 return 才能测试成功,这个坑我学习的时候也踩到了,所以给大家说一下,希望大家不要踩坑。
# 异步代码的测试方法 - 3 不存在接口的测试方法
后台需求不允许前台访问时,这时候就会返回 404(页面不存在),这时候在测试时也存在一些坑
继续打开 fetchData.test.js
文件,然后编写测试代码如下,注意这个地址是不存在的,也就是返回 404
export const fetchThreeData = ()=>{ | |
return axios.get('http://a.jspang.com/jestTest_error.json') | |
} |
这时候可能很多小伙伴说测试 404 直接用 catch
就可以了,很简单,然后代码写成了这样。
test('FetchThreeData 测试', ()=>{ | |
return fetchThreeData().catch((e)=>{ | |
//console.log(e.toString()) | |
expect(e.toString().indexOf('404')> -1).toBe(true) | |
}) | |
}) |
但这样是错误的,比如现在我们把异步请求代码改正确后,我们再走一下测试,还是可以通过测试的。 现在把网址改成正确的:(http://a.jspang.com/jestTest.json)
那这是为什么那?因为测试用例使用了 catch
方法,也就是说只有出现异常的时候才会走这个方法,而现在没有出现异常,就不会走这个测试方法,Jest 就默认这个用例通过了测试。
这个也算是一个坑,想改这个坑也非常简单,只要使用 expect.assertions(1)
就可以了,这个代码的意思是 “断言,必须需要执行一次 expect 方法才可以通过测试”。
修改过后的代码就变成了这个样子
test('FetchThreeData 测试', ()=>{ | |
expect.assertions(1) // 断言,必须执行一次 expect | |
return fetchThreeData().catch((e)=>{ | |
expect(e.toString().indexOf('404')> -1).toBe(true) | |
}) | |
}) |
这时候测试用例就无法正常通过测试了,因为此时我们的地址是存在并正确返回结果的。我们需要改成错误的地址,才能通过测试。(http://a.jspang.com/jestTest_error.json)
# 异步代码的测试方法 - 4async...await
上面异步测试用例时我使用了 return
的形式,这只是其中的一种方法,还有另一种方法,就是使用 async...await...
的这种语法形式来写测试用例。两种语法没有好坏之分,就看自己习惯和容易理解那种方法。
还是文件 fetchData.js 中,编写一个新的方法:
export const fetchFourData = ()=>{ | |
return axios.get('http://a.jspang.com/jestTest.json') | |
} |
注意,这时候地址是正确的,也就是可以正常返回结果的。
# async...await 编写测试代码
这时候我们的代码使用 async....await...
的形式,这里我们还使用了 resolves
用于把现有对象转换成 Promise
对象,然后使用 Jest
中的 toMatchObject
进行匹配对象中的属性。
test('FetchFourData 测试', async()=>{ | |
//resolves 把现有对象转换成 Promise 对象, | |
//toMatchObject 匹配对象中的属性 | |
await expect(fetchFourData()).resolves.toMatchObject({ | |
data:{ | |
success:true | |
} | |
}) | |
}) |
写完上面的代码就可以出正确的结果了,但是这种方法还是有点抽象的,需要用 resolves 转换一下。有没有简单方法,答案是肯定的。我们可以把上面的测试方法写成这样。
test('FetchFourData 测试', async()=>{ | |
const response = await fetchFourData() | |
expect(response.data).toEqual({ | |
success : true | |
}) | |
}) |
这就是用 async...await...
来进行异步代码测试。