准备条件
以第1节教程的创建的目录和代码为基础进行讲解。如果没有看过第1节教程,请关注我,查看以往该系列的文章
在讲匹配器之前,我们先来将上节中index.test.js
中基础代码讲解一下
import { sum } from './index'
test('测试 sum', () => {
expect(sum(1, 2)).toBe(3)
})
test
方法我们称做测试用例,接收两个参数,第一个参数是测试的名称,第二个参数是个函数,在函数内可以写一些测试逻辑expect
顾名思义就是期望的意思,expect(sum(1, 2)).toBe(3)
意思就是期望这个sum(1, 2)
的返回值和3
相等,整体称做为断言toBe
就是一个匹配器,匹配expect的值是否和匹配器中的值相等,也就是我们今天要讲的主题
既然了解我们之前写的代码的意思了,我们就开始今天的主题 匹配器,这些匹配器可以复制到index.test.js
进行测试
为了不用每次都启用命令npm run test
,可以在package.json
中的test命令加上--watchAll,这样文件更改就可以自动重新测试
.toBe(value):匹配值,相当于===
const can = {
name: 'pamplemousse'
};
test('has a sophisticated name', () => {
expect(can.name).toBe('pamplemousse');
});
注意点:
- 不能用于测试浮点数比如
expect(0.1+0.2).toBe(0.3)
,如果需要这样测试,可以使用toBeCloseTo
- 不能用于引用类型的检查
.toEqual(value):匹配值,只匹配内容不匹配引用,可以用于引用类型的匹配
const can1 = {
flavor: 'grapefruit',
ounces: 12,
};
const can2 = {
flavor: 'grapefruit',
ounces: 12,
};
test('have all the same properties', () => {
expect(can1).toEqual(can2);
});
注意点:
- 不能用于两个抛出异常的匹配
.toBeNull():匹配null
function bloop() {
return null;
}
test('bloop returns null', () => {
expect(bloop()).toBeNull();
});
注意点:
- .toBeNull()和.toBe(null)的作用是一样的
.toBeUndefined():匹配undefined
test('test undefined', () => {
let name
let age = undefined
expect(name).toBeUndefined()
expect(age).toBeUndefined()
})
注意点:
- .toBeUndefined()和.toBe(undefined)的作用是一样的
.toBeNaN():匹配NaN
test('passes when value is NaN', () => {
expect(NaN).toBeNaN();
});
.toBeTruthy():匹配结果为true的值
test('test true', () => {
let name = 'Jsoning'
let tag = true
let age = 26
let obj = {}
expect(name).toBeTruthy()
expect(tag).toBeTruthy()
expect(age).toBeTruthy()
expect(obj).toBeTruthy()
})
注意点:
- 在js中
false
,0
,''
,null
,undefined
,NaN
都会被自动转换成false
.toBeFalsy():匹配结果为false的值
test('test false', () => {
let name = null
let tag = false
let age = 0
let str = ''
let und = undefined
let nan = NaN
expect(name).toBeFalsy()
expect(tag).toBeFalsy()
expect(age).toBeFalsy()
expect(str).toBeFalsy()
expect(und).toBeFalsy()
expect(nan).toBeFalsy()
})
注意点:
- 在js中
false
,0
,''
,null
,undefined
,NaN
都会被自动转换成false
.toBeDefined():匹配已定义的值
test('test toBeDefined', () => {
let name = ''
let age = 26
expect(name).toBeDefined()
expect(age).toBeDefined()
})
.not:对后续的匹配取反
test('test not', () => {
let name = 'Jsoning'
let n = null
expect(name).toBe('Jsoning')
expect(name).not.toBe('Json') //匹配值不为Json
expect(n).toBeNull()
expect(n).not.toBeUndefined() //匹配值不为undefined
})
.toBeGreaterThan(number):匹配大于number的数字
test('test toBeGreaterThan', () => {
expect(10).toBeGreaterThan(9)
})
.toBeGreaterThanOrEqual(number):匹配大于等于number的数字
test('test toBeGreaterThanOrEqual', () => {
expect(10).toBeGreaterThanOrEqual(9)
expect(10).toBeGreaterThanOrEqual(10)
})
.toBeLessThan(number):匹配小于number的数字
test('test toBeLessThan', () => {
expect(1).toBeLessThan(2)
})
.toBeLessThanOrEqual(number):匹配小于等于number的数字
test('test toBeLessThanOrEqual', () => {
expect(1).toBeLessThanOrEqual(1)
expect(1).toBeLessThanOrEqual(2)
})
.toBeCloseTo(number, numDigits?):匹配指定位数的浮点数
test('test toBeCloseTo', () => {
// 0.1 + 0.2 = 0.30000000000000004
expect(0.1+0.2).toBeCloseTo(0.3, 5) //匹配5位小数
})
.toMatch(regexpOrString):检查字符串是否匹配
test('test toMatch', () => {
let str = 'abcdefg'
expect(str).toMatch('ab')
expect(str).toMatch(/[a-z]/)
})
.toMatchObject(object):匹配对象/数组是否属于子集
test('test toMatchObject', () => {
let obj = {
name: 'Jsoning',
age: 24,
area: 'bj'
}
let arr = [ { foo: 'bar', name: 'Jsoning' }, { baz: 1, age: 24 } ]
expect(obj).toMatchObject({
name: 'Jsoning'
})
expect(obj).toMatchObject({
name: 'Jsoning',
age: 24,
area: 'bj'
})
expect(arr).toMatchObject([
{
foo: 'bar'
},
{
baz: 1
}
])
})
.toContain(item):匹配数组/Set/字符串中是否包含item
test('test toContain', () => {
let name = 'Jsoning'
let arr = ['Jsoning', 'age']
let set = new Set(arr)
expect(name).toContain('Json')
expect(arr).toContain('Jsoning')
expect(set).toContain('age')
})
注意点:
- 不能检查arr/set中的对象,比如[{ name: 'Jsoning' }]
.toContainEqual(item):和.toContain类似,必须完全匹配,但是可以匹配数组内对象
test('test toContainEqual', () => {
let name = 'Jsoning'
let arr = ['Jsoning', 'age', { name: 'Jsoning', age: 24 }]
let set = new Set(arr)
// expect(name).toContainEqual('Json') // 错误示例
expect(arr).toContainEqual('Jsoning')
expect(set).toContainEqual('age')
//expect(set).toContainEqual({ name: 'Jsoning' }) // 错误示例
expect(set).toContainEqual({ name: 'Jsoning', age: 24 })
})
.toHaveLength(number):判断对象是否有length属性,并检查是否匹配
test('test toHaveLength', () => {
expect([1, 2, 3]).toHaveLength(3);
expect('abc').toHaveLength(3);
})
注意点:
- 这里不能进行对象的判断
.toBeInstanceOf(Class):匹配实例是否通过class构造函数实例出来
test('test toBeInstanceOf', () => {
class A { }
expect(new A()).toBeInstanceOf(A);
expect(() => { }).toBeInstanceOf(Function);
expect(new A()).toBeInstanceOf(Function); // throws
})
.toThrow(error?)/.toThrowError(error?):匹配异常
test('test toContainEqual', () => {
function throwFun() {
throw new Error('123abc')
}
expect(() => throwFun()).toThrow()
expect(() => throwFun()).toThrow('123')
expect(() => throwFun()).toThrow(/a/)
})
注意点:
- expect传入一个函数才可以匹配到异常
.toHaveBeenCalled()/.toBeCalled():检查函数是否被执行
function callback(fn) {
fn()
}
test('test toHaveBeenCalled', () => {
const fn = jest.fn(); //通过mock创建一个函数,后面教程会讲到
callback(fn)
expect(fn).toHaveBeenCalled();
expect(fn).toBeCalled();
})
.toHaveBeenCalledWith(arg1, arg2, ...)/.toBeCalledWith(arg1, arg2, ...):检查调用函数传入值是否匹配
function callback(fn) {
fn(123)
}
test('test toHaveBeenCalledWith', () => {
const fn = jest.fn();
callback(fn)
expect(fn).toHaveBeenCalledWith(123);
expect(fn).toBeCalledWith(123);
expect(fn.mock.calls[0]).toEqual([123])
})
.toHaveBeenLastCalledWith(arg1, arg2, ...)/.lastCalledWith(arg1, arg2, ...):检查最后一次调用函数传入值是否匹配
function callback(fn, arg) {
fn(arg)
}
test('test toHaveBeenLastCalledWith', () => {
const fn = jest.fn();
callback(fn, 123)
callback(fn, 456)
expect(fn).toHaveBeenLastCalledWith(456);
expect(fn).lastCalledWith(456);
})
.toHaveBeenNthCalledWith(nthCall, arg1, arg2, ....)/.nthCalledWith(nthCall, arg1, arg2, ...):检查第nth次调用函数传入值是否匹配
function callback(fn, arg) {
fn(arg)
}
test('test toHaveBeenLastCalledWith', () => {
const fn = jest.fn();
callback(fn, 123)
callback(fn, 456)
callback(fn, 789)
expect(fn).toHaveBeenNthCalledWith(2, 456);
expect(fn).nthCalledWith(2, 456);
})
.toHaveBeenCalledTimes(number)/.toBeCalledTimes(number):检查函数被调用次数是否匹配
function callback(fn, arg) {
fn(arg)
}
test('test toHaveBeenCalledTimes', () => {
const fn = jest.fn();
callback(fn, 123)
callback(fn, 123)
callback(fn, 123)
expect(fn).toHaveBeenCalledTimes(3);
expect(fn).toBeCalledTimes(3);
})
.toHaveReturned()/.toReturn():检查函数是否有返回值
test('test toHaveReturned', () => {
const fn = jest.fn(() => 123);
fn()
expect(fn).toHaveReturned();
expect(fn).toReturn();
})
.toHaveReturnedTimes(number)/.toReturnTimes(number):检查函数返回值得次数
test('test toHaveReturnedTimes', () => {
const fn = jest.fn(() => 123);
fn()
fn()
expect(fn).toHaveReturnedTimes(2);
expect(fn).toReturnTimes(2);
})
.toHaveReturnedWith(value)/.toReturnWith(value):检查函数返回值是否匹配
test('test toHaveReturnedWith', () => {
const fn = jest.fn(() => 123);
fn()
expect(fn).toHaveReturnedWith(123);
expect(fn).toReturnWith(123);
})
.toHaveLastReturnedWith(value)/.lastReturnedWith(value):检查最后一次函数返回值是否匹配
test('test toHaveLastReturnedWith', () => {
const fn = jest.fn((arg) => arg);
fn(123)
fn(456)
expect(fn).toHaveLastReturnedWith(456);
expect(fn).lastReturnedWith(456);
})
.toHaveNthReturnedWith(nthCall, value)/.nthReturnedWith(nthCall, value):检查第nth次调用函数返回值是否匹配
test('test toHaveNthReturnedWith', () => {
const fn = jest.fn((arg) => arg);
fn(123)
fn(456)
expect(fn).toHaveNthReturnedWith(1, 123);
expect(fn).nthReturnedWith(2, 456);
})
到目前为止,jest的匹配器绝大部分都已经讲完了,,还有极少一些不常用的没有列举。大家最好自己运行试一下,加深理解。一下全部记住也是有些困难的,我们只要记住常用的就可以了,剩下的用到可以查询文档
本人能力有限,文章可能会有不正确或者不恰当的部分,希望你可以指出