準備條件
以第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的匹配器絕大部分都已經講完了,,還有極少一些不常用的沒有列舉。大家最好自己運行試一下,加深理解。一下全部記住也是有些困難的,我們只要記住常用的就可以了,剩下的用到可以查詢文檔
基礎的知識點總是枯燥無味的,靜下心去學習,也會讓我們思考到更多!!!
本人能力有限,文章可能會有不正確或者不恰當的部分,希望你可以指出