二期了,主要想从匹配器说起,先列出常用的三种匹配器吧
匹配器
真假匹配器
1.toBe: 绝对匹配
2.toEqual: 模糊匹配 --引用类型指针方向不同
3.tonull: 匹配null
4.toBeTruthy: 匹配为真
5.toBeFalsy: 匹配为假
数字匹配器
1.toBeGreaterThan(val): 大于val
2.toBeLessThan(val): 小于val
3.toBeGreaterThanorEqual(val): 大于等于val
4.toBeCloseTo(val): 等于 --针对浮点数
交集并集匹配器
1.toMatch(val) : 字符串包含val
2.toContain(val): 数组中包含val
3.toThrow(val): 匹配抛出异常val
官网的匹配器还有很多,可以去看看jest官网
写几个例子大家就知道用法了
例子1
//eg1
test('今天不参与大保健',()=>{
let obj = {
name:'ls',
age:20
}
expect(obj).toBe({
name:'ls',
age:20
})
})
结果
//报错
FAIL ./honglanman.test.js
● 今天不参与大保健
expect(received).toBe(expected) // Object.is equality
If it should pass with deep equality, replace "toBe" with "toStrictEqual"
Expected: {"age": 20, "name": "ls"}
Received: serializes to the same string
16 | age:20
17 | }
> 18 | expect(obj).toBe({
| ^
19 | name:'ls',
20 | age:20
21 | })
at Object.<anonymous> (honglanman.test.js:18:15)
原因:引用数据指针指向不同应该使用的匹配器为toEqual
例子2
//eg2
test('今天不参与大保健',()=>{
let a = 5
expect(a).toBeGreaterThan(4)
})
结果:大获成功
异步代码
异步在我们的前端代码中出现的频率也是非常的高,所以针对异步代码,我们也要做个测试。首先基于express搭建一个简易的服务器吧,在跟目录下新增server.js文件
//服务器
import { createRequire } from 'module';
const require = createRequire(import.meta.url); //新的commonJS无法直接使用require,需要此方法引入
const express = require('express')
const { listen } = require('express/lib/application')
const app = express()
app.get('/getdata',function(req,res){
console.log('请求到了')
res.send('hello world')
})
const port = 6000
app.listen(port,()=>{
console.log('server is running')
})
现在我们在本地的6000端口搭建了一个简单的服务,
在下载一个axios去请求它
import axios from 'axios'
let reqFun = function(){
return axios.get('http://127.0.0.1:6000/getdata').then((res)=>{
// console.log(res.data )
return res.data
}).catch((res)=>{
console.log(res + '错误')
})
}
export{reqFun}
结果
hello world
此时创建一个就test文件,去做异步测试
import {reqFun} from './fetch/fetch.js'
test('异步一',async()=>{
let res = await reqFun()
expect(res.data).toEqual('hello world')
})
结果 - 报跨域错误,此时我们尝试使用cors解决跨域问题,但是没有生效
查看文档发现官方也不建议直接发送请求并且提出了使用mock数据的解决方案
jest-mock
1.jest.fn()
Jest.fn()是创建Mock函数最简单的方式,如果没有定义函数内部的实现,jest.fn()会返回undefined作为返回值。
Jest.fn()所创建的Mock函数还可以设置返回值,定义内部实现或返回Promise对象。
开整
//普通函数
test('mock1',()=>{
let mockFun = jest.fn().mockReturnValue("Felix")
expect(mockFun()).tobe('Felix')
})
//内部执行
test('mock2',()=>{
let mockFun = jest.fn((x)=>x+5)
expect(mockFun(5)).tobe(10)
})
//异步函数
test('mock3',async()=>{
let mockFun = jest.fn().mockResolvedValue("Felix");
let ret = await mockFun()
expect(ret).toBe("Felix")
})
2.jest.mock()
一般使用在监听引用类型文件时,需要mock该文件,直接开整先
首先创建一个untail文件
export let add = function(a,b){
return a + b
}
export let reduce = function(a,b){
return a - b
}
再创建一个fun文件
import {add,reduce} from './untail'
export let fun1 = function(a,b){
return add(a,b)
}
然后去测试fun文件,创建fun.test文件
import {add} from './untail'
import {fun1} from './fun'
test('ceshifun',()=>{
console.log(fun1(3,1))
expect(add).toBeCalledTimes(1)
})
结果
FAIL ./fun.test.js
● Console
console.log fun.test.js:11
4
● ceshifun
expect(received).toBeCalledTimes(expected)
Matcher error: received value must be a mock or spy function
Received has type: function
Received has value: [Function add]
10 | test('ceshifun',()=>{
11 | console.log(fun1(3,1))
> 12 | expect(add).toBeCalledTimes(1)
| ^
13 | })
at Object.<anonymous> (fun.test.js:12:15)
虽然执行可add函数但是并没有完成监听,收到的值必须被mock
import {add} from './untail'
import {fun1} from './fun'
import jestConfig from './jest.config'
jest.mock('./untail',()=>{
return{
add:jest.fn(() => 3)
}
})
test('ceshifun',()=>{
console.log(fun1(3,1))
expect(add).toBeCalledTimes(1)
})
结果成功执行
3.jest.spyOn()
Jest.spyOn()方法同样创建一个mock函数,但是该mock函数不仅能够捕获函数的调用情况,还可以正常的执行被spy的函数。实际上,jest.spyOn()是jest.fn()的语法糖,它创建了一个和被spy的函数具有相同内部代码的mock函数。
import untail from './untail'
import {fun1} from './fun'
import jestConfig from './jest.config'
let add = jest.spyOn(untail,'add')
test('ceshifun',()=>{
console.log(fun1(3,1))
expect(add).toBeCalledTimes(1)
})
钩子函数以及测试分组
beforeAll(fun):在所有的测试用例前,
afterAll(fun):在所有的测试用例后,
beforeEach(fun):在每个测式用例前,
afterEach(fun):在每个测式用例后,
你可以使用 describe 关键字对 test 进行分组。有以下两条规则:
1、上面四个钩子可以放在 describe 内,放在 describe 内部的钩子仅对当前分组生效。
2、当有多个 describe 时,会先执行所有的 describe,再执行所有的 test。
beforeAll(() => {
console.log('outer-beforeAll');
})
afterAll(() => {
console.log('outer-afterAll');
})
beforeEach(() => {
console.log('outer-beforeEach');
})
afterEach(() => {
console.log('outer-afterEach');
})
describe('group 1', () => {
beforeEach(() => {
console.log('inner-group-1-beforeEach');
})
afterEach(() => {
console.log('inner-group-1-afterEach');
})
console.log('inner-group-1');
test('', () => {
console.log('inner-group-1-test');
expect('apple').toBe('apple');
})
})
describe('group 2', () => {
console.log('inner-group-2');
test('', () => {
console.log('inner-group-2-test');
expect('banana').toBe('banana');
})
})
/**
* 打印顺序为:
* 1、inner-group-1
* 2、inner-group-2
* 3、outer-beforeAll
* 4、outer-beforeEach
* 5、inner-group-1-beforeEach
* 6、inner-group-1-test
* 7、inner-group-1-afterEach
* 8、outer-afterEach
* 9、outer-beforeEach
* 10、inner-group-2-test
* 11、outer-afterEach
* 12、outer-afterAll
*/
至此,jest的基本应用语法和规则就结束了
告辞~