Jest 斷言歸納

Jest 實在是很方便仰美,上手簡單妻率,幾乎零配置。記錄一下學習 Jest matchers盟戏。附上大部分說明及示例绪妹。

普通匹配器

  • toBe - toBe 使用 Object.is 來測試是否完全相等
  • .not - 用來測試相反的用例
  • .toEqual - 如果你想檢查某個對象的值,請改用 toEqual。

toBe

最簡單的測試值的方法是看是否精確匹配。

test('two plus two is four', () => { 
    expect(2 + 2).toBe(4); 
});

toEqual

如果你想檢查某個對象的值累舷,請改用 toEqual。

test('object assignment', () => { 
    const data = {one: 1}; 
    data['two'] = 2; 
     expect(data).toEqual({one: 1, two: 2}); 
});

.not

用來測試相反的用例

test('null', () => {
  const n = null;
  expect(n).not.toBeUndefined();
  expect(n).not.toBeTruthy();
});

布爾值匹配器

  • toBeNull 只匹配 null
  • toBeUndefined 只匹配 undefined
  • toBeDefined 與 toBeUndefined 相反
  • toBeTruthy 匹配任何 if 語句為真
  • toBeFalsy 匹配任何 if 語句為假
test('null', () => {
  const n = null;
  expect(n).toBeNull();
  expect(n).toBeDefined();
  expect(n).not.toBeUndefined();
  expect(n).not.toBeTruthy();
  expect(n).toBeFalsy();
});

test('zero', () => {
  const z = 0;
  expect(z).not.toBeNull();
  expect(z).toBeDefined();
  expect(z).not.toBeUndefined();
  expect(z).not.toBeTruthy();
  expect(z).toBeFalsy();
});

數(shù)字匹配器

  • .toBeGreaterThan() - 大于
  • .toBeGreaterThanOrEqual() 大于等于
  • .toBeLessThan() - 小于
  • .toBeLessThanOrEqual() - 小于等于
  • .toBeCloseTo() - 浮點數(shù)比較

toBeGreaterThan婶肩、toBeGreaterThanOrEqual、toBeLessThan貌夕、toBeLessThanOrEqual

test('two plus two', () => { 
const value = 2 + 2; 
 expect(value).toBeGreaterThan(3); 
 expect(value).toBeGreaterThanOrEqual(3.5); 
 expect(value).toBeLessThan(5); 
 expect(value).toBeLessThanOrEqual(4.5);

// toBe 和 toEqual 對于數(shù)字來說是一樣的
 expect(value).toBe(4); 
 expect(value).toEqual(4); 
});

.toBeCloseTo()

對于比較浮點數(shù)的相等律歼,應該使用 toBeCloseTo

test('兩個浮點數(shù)字相加', () => {
    const value = 0.1 + 0.2;        // 0.30000000000000004 
    expect(value).toBe(0.3);        // 這句會報錯,因為 js 浮點數(shù)有舍入誤差
    expect(value).toBeCloseTo(0.3); // 這句可以運行
});

字符串匹配器

  • toMatch - 正則表達式的字符
  • .toHaveLength(number) - 判斷一個有長度的對象的長度

toMatch

正則表達式的字符

test('there is no I in team', () => {
  expect('team').not.toMatch(/I/);
});

test('but there is a "stop" in Christoph', () => {
  expect('Christoph').toMatch(/stop/);
});

.toHaveLength(number)

判斷一個有長度的對象的長度

expect([1, 2, 3]).toHaveLength(3);
expect('abc').toHaveLength(3);
expect('').not.toHaveLength(5);

數(shù)組匹配器

  • .toContain(item) - 判斷數(shù)組是否包含特定子項
  • .toContainEqual(item) - 判斷數(shù)組中是否包含一個特定對象

.toContain

判斷數(shù)組是否包含特定子項

const shoppingList = [
  'diapers',
  'kleenex',
  'trash bags',
  'paper towels',
  'beer',
];

test('購物清單(shopping list)里面有啤酒(beer)', () => {
  expect(shoppingList).toContain('beer');
});

.toContainEqual(item)

可以判斷數(shù)組中是否包含一個特定對象蜂嗽,類似 toEqual 與 toContain 的結合

function myBeverages() {
    return [
        {delicious: true, sour: false},
        {delicious: false, sour: true}
    ]
}
test('is delicious and not sour', () => {
    const myBeverage = {delicious: true, sour: false};
    expect(myBeverages()).toContainEqual(myBeverage);
});

對象匹配器

  • .toMatchObject(object) - 判斷一個對象嵌套的 key 下面的 value 類型
  • .toHaveProperty(keyPath, value) - 判斷在指定的 path 下是否有這個屬性

.toMatchObject(object)

判斷一個對象嵌套的 key 下面的 value 類型苗膝,需要傳入一個對象。

const houseForSale = {
  bath: true,
  bedrooms: 4,
  kitchen: {
    amenities: ['oven', 'stove', 'washer'],
    area: 20,
    wallColor: 'white',
  },
};
const desiredHouse = {
  bath: true,
  kitchen: {
    amenities: ['oven', 'stove', 'washer'],
    wallColor: expect.stringMatching(/white|yellow/),
  },
};

test('the house has my desired features', () => {
  expect(houseForSale).toMatchObject(desiredHouse);
});

.toHaveProperty(keyPath, value)

判斷在指定的 path 下是否有這個屬性植旧,嵌套的 path 可以用 '.'分割辱揭,也可以用數(shù)組。

// Object containing house features to be tested
const houseForSale = {
  bath: true,
  bedrooms: 4,
  kitchen: {
    amenities: ['oven', 'stove', 'washer'],
    area: 20,
    wallColor: 'white',
  },
};

test('this house has my desired features', () => {
  // Simple Referencing
  expect(houseForSale).toHaveProperty('bath');
  expect(houseForSale).toHaveProperty('bedrooms', 4);

  expect(houseForSale).not.toHaveProperty('pool');

  // Deep referencing using dot notation
  expect(houseForSale).toHaveProperty('kitchen.area', 20);
  expect(houseForSale).toHaveProperty('kitchen.amenities', [
    'oven',
    'stove',
    'washer',
  ]);

  expect(houseForSale).not.toHaveProperty('kitchen.open');

  // Deep referencing using an array containing the keyPath
  expect(houseForSale).toHaveProperty(['kitchen', 'area'], 20);
  expect(houseForSale).toHaveProperty(
    ['kitchen', 'amenities'],
    ['oven', 'stove', 'washer'],
  );
  expect(houseForSale).toHaveProperty(['kitchen', 'amenities', 0], 'oven');

  expect(houseForSale).not.toHaveProperty(['kitchen', 'open']);
});

自定義匹配器

使用expect.extend將自己的匹配器添加到Jest病附。自定義匹配器需要返回一個包含兩個key 的對象

{
    pass:false //‘布爾值’问窃, 
    message: () => 'message string' //‘函數(shù),該函數(shù)返回一個提示信息’
}
expect.extend({
  toBeDivisibleBy(received, argument) {
    const pass = received % argument == 0;
    if (pass) {
      return {
        message: () =>
          `expected ${received} not to be divisible by ${argument}`,
        pass: true,
      };
    } else {
      return {
        message: () => `expected ${received} to be divisible by ${argument}`,
        pass: false,
      };
    }
  },
});

test('even and odd numbers', () => {
  expect(100).toBeDivisibleBy(2);
  expect(101).not.toBeDivisibleBy(2);
});

這些幫助函數(shù)可以在自定義匹配器中的this中找到:

  • this.isNot
  • this.equals(a, b)
  • this.utils(matcherHint, printExpected and printReceived)

其他

  • toThrow - 要測試的特定函數(shù)會在調用時拋出一個錯誤
  • .resolves 和 .rejects - 用來測試 promise
  • .toHaveBeenCalled() - 用來判斷一個函數(shù)是否被調用過
  • .toHaveBeenCalledTimes(number) - 判斷函數(shù)被調用過幾次

toThrow

要測試的特定函數(shù)會在調用時拋出一個錯誤

function compileAndroidCode() {
  throw new ConfigError('you are using the wrong JDK');
}

test('compiling android goes as expected', () => {
  expect(compileAndroidCode).toThrow();
  expect(compileAndroidCode).toThrow(ConfigError);

  // You can also use the exact error message or a regexp
  expect(compileAndroidCode).toThrow('you are using the wrong JDK');
  expect(compileAndroidCode).toThrow(/JDK/);
});

.resolves 和 .rejects

用來測試 promise


//resolves
test('resolves to lemon', () => {
  // make sure to add a return statement
  return expect(Promise.resolve('lemon')).resolves.toBe('lemon');
});

//rejects
test('resolves to lemon', async () => {
  await expect(Promise.resolve('lemon')).resolves.toBe('lemon');
  await expect(Promise.resolve('lemon')).resolves.not.toBe('octopus');
});

.toHaveBeenCalled()

.toHaveBeenCalled() 也有個別名是.toBeCalled()完沪,用來判斷一個函數(shù)是否被調用過域庇。

describe('drinkAll', () => {
  test('drinks something lemon-flavored', () => {
    const drink = jest.fn();
    drinkAll(drink, 'lemon');
    expect(drink).toHaveBeenCalled();
  });

  test('does not drink something octopus-flavored', () => {
    const drink = jest.fn();
    drinkAll(drink, 'octopus');
    expect(drink).not.toHaveBeenCalled();
  });
});

.toHaveBeenCalledTimes(number)

和 toHaveBeenCalled 類似,判斷函數(shù)被調用過幾次覆积。

test('drinkEach drinks each drink', () => {
  const drink = jest.fn();
  drinkEach(drink, ['lemon', 'octopus']);
  expect(drink).toHaveBeenCalledTimes(2);
});

未整理部分

lastCalledWith

toBeCalledWith

toHaveBeenCalledWith

toHaveBeenLastCalledWith

toBeInstanceOf

toMatchSnapshot

toThrowError

toThrowErrorMatchingSnapshot

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末听皿,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子宽档,更是在濱河造成了極大的恐慌尉姨,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吗冤,死亡現(xiàn)場離奇詭異又厉,居然都是意外死亡,警方通過查閱死者的電腦和手機椎瘟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進店門覆致,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人肺蔚,你說我怎么就攤上這事煌妈。” “怎么了宣羊?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵声旺,是天一觀的道長。 經(jīng)常有香客問我段只,道長腮猖,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任赞枕,我火速辦了婚禮澈缺,結果婚禮上,老公的妹妹穿的比我還像新娘炕婶。我一直安慰自己姐赡,他們只是感情好,可當我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布柠掂。 她就那樣靜靜地躺著项滑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪涯贞。 梳的紋絲不亂的頭發(fā)上枪狂,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天危喉,我揣著相機與錄音,去河邊找鬼州疾。 笑死辜限,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的严蓖。 我是一名探鬼主播薄嫡,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼颗胡!你這毒婦竟也來了毫深?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤毒姨,失蹤者是張志新(化名)和其女友劉穎哑蔫,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體手素,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡鸳址,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了泉懦。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片稿黍。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖崩哩,靈堂內(nèi)的尸體忽然破棺而出巡球,到底是詐尸還是另有隱情,我是刑警寧澤邓嘹,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布酣栈,位于F島的核電站,受9級特大地震影響汹押,放射性物質發(fā)生泄漏矿筝。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一棚贾、第九天 我趴在偏房一處隱蔽的房頂上張望窖维。 院中可真熱鬧,春花似錦妙痹、人聲如沸铸史。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽琳轿。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間崭篡,已是汗流浹背挪哄。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留媚送,地道東北人中燥。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓寇甸,卻偏偏與公主長得像塘偎,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子拿霉,可洞房花燭夜當晚...
    茶點故事閱讀 43,612評論 2 350

推薦閱讀更多精彩內(nèi)容