前端自動化測試jest教程2-匹配器matchers

在這裏插入圖片描述

準備條件

以第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的匹配器絕大部分都已經講完了,,還有極少一些不常用的沒有列舉。大家最好自己運行試一下,加深理解。一下全部記住也是有些困難的,我們只要記住常用的就可以了,剩下的用到可以查詢文檔

基礎的知識點總是枯燥無味的,靜下心去學習,也會讓我們思考到更多!!!

本人能力有限,文章可能會有不正確或者不恰當的部分,希望你可以指出

關注公衆號,和我一起學習前端必備技能,前端自動化測試jest在這裏插入圖片描述

發佈了22 篇原創文章 · 獲贊 15 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章