用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...来进行异步代码测试。