Jest expect API

2021-09-18 20:53 更新

在編寫(xiě)測(cè)試時(shí),經(jīng)常需要檢查值是否滿(mǎn)足特定條件。expect可以訪(fǎng)問(wèn)許多匹配器(Matchers),這些匹配器讓你驗(yàn)證不同的事物。

有關(guān) Jest 社區(qū)維護(hù)的其他 Jest 匹配器,請(qǐng)查看jest-extended

方法

參考

?expect(value)?

每次要測(cè)試一個(gè)值時(shí)都會(huì)使用?expect?函數(shù)。 你很少會(huì)自己調(diào)用?expect?。 相反,你會(huì)使用?expect?和“matcher”函數(shù)來(lái)斷言有關(guān)值的內(nèi)容。

很容易理解這一點(diǎn)的一個(gè)例子。 假設(shè)你有一個(gè)方法?bestLaCroixFlavor()?,它應(yīng)該返回字符串?'grapefruit'?。 以下是如何測(cè)試:

  1. test('the best flavor is grapefruit', () => {
  2. expect(bestLaCroixFlavor()).toBe('grapefruit');
  3. });

在這種情況下,?toBe?是匹配器功能。有許多不同的匹配器函數(shù),記錄如下,來(lái)幫助你測(cè)試不同的東西。

?expect?的參數(shù)應(yīng)該是代碼產(chǎn)生的值,匹配器的任何參數(shù)應(yīng)該是正確的值。 如果混合使用,測(cè)試仍然可以工作,但是失敗測(cè)試的錯(cuò)誤信息將會(huì)顯得奇怪。

expect.extend(matchers)

可以使用?expect.extend?將自己的匹配器添加到Jest。 例如,假設(shè)你正在測(cè)試一個(gè)數(shù)字實(shí)用程序庫(kù),并且經(jīng)常斷言數(shù)字出現(xiàn)在其他數(shù)字的特定范圍內(nèi)??梢詫⑵涑橄鬄?toBeWithinRange?匹配器:

  1. expect.extend({
  2. toBeWithinRange(received, floor, ceiling) {
  3. const pass = received >= floor && received <= ceiling;
  4. if (pass) {
  5. return {
  6. message: () =>
  7. `expected ${received} not to be within range ${floor} - ${ceiling}`,
  8. pass: true,
  9. };
  10. } else {
  11. return {
  12. message: () =>
  13. `expected ${received} to be within range ${floor} - ${ceiling}`,
  14. pass: false,
  15. };
  16. }
  17. },
  18. });
  19. test('numeric ranges', () => {
  20. expect(100).toBeWithinRange(90, 110);
  21. expect(101).not.toBeWithinRange(0, 100);
  22. expect({apples: 6, bananas: 3}).toEqual({
  23. apples: expect.toBeWithinRange(1, 10),
  24. bananas: expect.not.toBeWithinRange(11, 20),
  25. });
  26. });

注意:在 TypeScript 中,?@types/jest?例如使用時(shí),可以?toBeWithinRange?像這樣聲明新的匹配器:

  1. declare global {
  2. namespace jest {
  3. interface Matchers<R> {
  4. toBeWithinRange(a: number, b: number): R;
  5. }
  6. }
  7. }

異步匹配器

?expect.extend?還支持異步匹配器。異步匹配器返回一個(gè) Promise,因此你需要等待返回的值。讓我們使用一個(gè)示例匹配器來(lái)說(shuō)明它們的用法。我們將實(shí)現(xiàn)一個(gè)名為 的匹配器?toBeDivisibleByExternalValue?,從外部源中提取可整除數(shù)。

  1. expect.extend({
  2. async toBeDivisibleByExternalValue(received) {
  3. const externalValue = await getExternalValueFromRemoteSource();
  4. const pass = received % externalValue == 0;
  5. if (pass) {
  6. return {
  7. message: () =>
  8. `expected ${received} not to be divisible by ${externalValue}`,
  9. pass: true,
  10. };
  11. } else {
  12. return {
  13. message: () =>
  14. `expected ${received} to be divisible by ${externalValue}`,
  15. pass: false,
  16. };
  17. }
  18. },
  19. });
  20. test('is divisible by external value', async () => {
  21. await expect(100).toBeDivisibleByExternalValue();
  22. await expect(101).not.toBeDivisibleByExternalValue();
  23. });

自定義匹配器 API

匹配器應(yīng)該返回帶有兩個(gè)鍵的對(duì)象(或?qū)ο蟮某兄Z)。?pass?指示是否存在匹配項(xiàng),?message?提供的函數(shù)不帶參數(shù),在失敗時(shí)返回錯(cuò)誤消息。 因此,當(dāng)?pass?為false時(shí),?message?應(yīng)該返回當(dāng)?expect(x).yourMatcher()?失敗時(shí)的錯(cuò)誤消息。 而當(dāng)?pass?為true時(shí), ?message?應(yīng)該返回當(dāng)?expect(x).not.yourMatcher()?失敗時(shí)的錯(cuò)誤信息。

匹配器使用傳遞給?expect(x)?的參數(shù)和傳遞給的參數(shù)調(diào)用?.yourMatcher(y, z)?:

  1. expect.extend({
  2. yourMatcher(x, y, z) {
  3. return {
  4. pass: true,
  5. message: () => '',
  6. };
  7. },
  8. });

這些輔助函數(shù)和屬性可以?this?在自定義匹配器中找到:

this.isNot

一個(gè)布爾值,讓你知道此匹配器是使用否定?.not?修飾符調(diào)用的,允許顯示清晰正確的匹配器提示(請(qǐng)參閱示例代碼)。

this.promise

一個(gè)字符串,允許顯示清晰正確的匹配器提示:

  • ?'rejects'?如果使用 ?promise.rejects?修飾符調(diào)用 ?matcher?
  • ?'resolves'?如果使用 ?promise.resolves?修飾符調(diào)用 ?matcher?
  • ?''? 如果沒(méi)有使用承諾修飾符調(diào)用匹配器

this.equals(a, b)

這是一個(gè)深度相等的函數(shù),如果兩個(gè)對(duì)象具有相同的值(遞歸),則返回?true?。

this.expand

一個(gè)布爾值,讓你知道這個(gè)匹配器是用一個(gè)?expand?選項(xiàng)調(diào)用的。當(dāng)使用?--expand?標(biāo)志調(diào)用 Jest 時(shí),?this.expand?可用于確定 Jest 是否應(yīng)顯示完整的差異和錯(cuò)誤。

this.utils

在?this.utils?上有一些有用的工具,主要由jest-matcher-utils導(dǎo)出。

最有用的是?matcherHint?,?printExpected?和?printReceived?很好地格式化錯(cuò)誤消息。例如,看一下?toBe?匹配器的實(shí)現(xiàn):

  1. const diff = require('jest-diff');
  2. expect.extend({
  3. toBe(received, expected) {
  4. const options = {
  5. comment: 'Object.is equality',
  6. isNot: this.isNot,
  7. promise: this.promise,
  8. };
  9. const pass = Object.is(received, expected);
  10. const message = pass
  11. ? () =>
  12. this.utils.matcherHint('toBe', undefined, undefined, options) +
  13. '\n\n' +
  14. `Expected: not ${this.utils.printExpected(expected)}\n` +
  15. `Received: ${this.utils.printReceived(received)}`
  16. : () => {
  17. const diffString = diff(expected, received, {
  18. expand: this.expand,
  19. });
  20. return (
  21. this.utils.matcherHint('toBe', undefined, undefined, options) +
  22. '\n\n' +
  23. (diffString && diffString.includes('- Expect')
  24. ? `Difference:\n\n${diffString}`
  25. : `Expected: ${this.utils.printExpected(expected)}\n` +
  26. `Received: ${this.utils.printReceived(received)}`)
  27. );
  28. };
  29. return {actual: received, message, pass};
  30. },
  31. });

這將打印如下內(nèi)容:

  1. expect(received).toBe(expected)
  2. Expected value to be (using Object.is):
  3. "banana"
  4. Received:
  5. "apple"

當(dāng)斷言失敗時(shí),錯(cuò)誤消息應(yīng)向用戶(hù)提供盡可能多的信號(hào),以便他們能夠快速解決問(wèn)題。應(yīng)該制作精確的失敗消息,以確保你的自定義斷言的用戶(hù)擁有良好的開(kāi)發(fā)人員體驗(yàn)。

自定義快照匹配器

要在自定義匹配器中使用快照測(cè)試,可以?jest-snapshot?從匹配器中導(dǎo)入和使用它。

這是一個(gè)快照匹配器,它修剪字符串以存儲(chǔ)給定長(zhǎng)度,?.toMatchTrimmedSnapshot(length)?:

  1. const {toMatchSnapshot} = require('jest-snapshot');
  2. expect.extend({
  3. toMatchTrimmedSnapshot(received, length) {
  4. return toMatchSnapshot.call(
  5. this,
  6. received.substring(0, length),
  7. 'toMatchTrimmedSnapshot',
  8. );
  9. },
  10. });
  11. it('stores only 10 characters', () => {
  12. expect('extra long string oh my gerd').toMatchTrimmedSnapshot(10);
  13. });
  14. /*
  15. Stored snapshot will look like:
  16. exports[`stores only 10 characters: toMatchTrimmedSnapshot 1`] = `"extra long"`;
  17. */

也可以為內(nèi)聯(lián)快照創(chuàng)建自定義匹配器,快照將正確添加到自定義匹配器中。但是,當(dāng)?shù)谝粋€(gè)參數(shù)是屬性匹配器時(shí),內(nèi)聯(lián)快照將始終嘗試附加到第一個(gè)參數(shù)或第二個(gè)參數(shù),因此無(wú)法在自定義匹配器中接受自定義參數(shù)。

  1. const {toMatchInlineSnapshot} = require('jest-snapshot');
  2. expect.extend({
  3. toMatchTrimmedInlineSnapshot(received) {
  4. return toMatchInlineSnapshot.call(this, received.substring(0, 10));
  5. },
  6. });
  7. it('stores only 10 characters', () => {
  8. expect('extra long string oh my gerd').toMatchTrimmedInlineSnapshot();
  9. /*
  10. The snapshot will be added inline like
  11. expect('extra long string oh my gerd').toMatchTrimmedInlineSnapshot(
  12. `"extra long"`
  13. );
  14. */
  15. });

expect.anything()

?expect.anything()?匹配除?null?或 之外的任何內(nèi)容?undefined???梢栽趦?nèi)部?toEqual?或?toBeCalledWith?代替文字值使用它。例如,如果要檢查是否使用非空參數(shù)調(diào)用了模擬函數(shù):

  1. test('map calls its argument with a non-null argument', () => {
  2. const mock = jest.fn();
  3. [1].map(x => mock(x));
  4. expect(mock).toBeCalledWith(expect.anything());
  5. });

expect.any(constructor)

?expect.any(constructor)?匹配使用給定構(gòu)造函數(shù)創(chuàng)建的任何內(nèi)容。可以在內(nèi)部?toEqual?或?toBeCalledWith?代替文字值使用它。例如,如果要檢查是否使用數(shù)字調(diào)用了模擬函數(shù):

  1. function randocall(fn) {
  2. return fn(Math.floor(Math.random() * 6 + 1));
  3. }
  4. test('randocall calls its callback with a number', () => {
  5. const mock = jest.fn();
  6. randocall(mock);
  7. expect(mock).toBeCalledWith(expect.any(Number));
  8. });

expect.arrayContaining(array)

?expect.arrayContaining(array)?匹配接收到的數(shù)組,該數(shù)組包含預(yù)期數(shù)組中的所有元素。也就是說(shuō),預(yù)期數(shù)組是接收數(shù)組的子集。因此,它匹配包含不在預(yù)期數(shù)組中的元素的接收數(shù)組。

可以使用它代替文字值:

  • 在?toEqual?或?toBeCalledWith?
  • 匹配?objectContaining?或?toMatchObject?
  1. describe('arrayContaining', () => {
  2. const expected = ['Alice', 'Bob'];
  3. it('matches even if received contains additional elements', () => {
  4. expect(['Alice', 'Bob', 'Eve']).toEqual(expect.arrayContaining(expected));
  5. });
  6. it('does not match if received does not contain expected elements', () => {
  7. expect(['Bob', 'Eve']).not.toEqual(expect.arrayContaining(expected));
  8. });
  9. });
  1. describe('Beware of a misunderstanding! A sequence of dice rolls', () => {
  2. const expected = [1, 2, 3, 4, 5, 6];
  3. it('matches even with an unexpected number 7', () => {
  4. expect([4, 1, 6, 7, 3, 5, 2, 5, 4, 6]).toEqual(
  5. expect.arrayContaining(expected),
  6. );
  7. });
  8. it('does not match without an expected number 2', () => {
  9. expect([4, 1, 6, 7, 3, 5, 7, 5, 4, 6]).not.toEqual(
  10. expect.arrayContaining(expected),
  11. );
  12. });
  13. });

expect.assertions(number)

?expect.assertions(number)?驗(yàn)證在測(cè)試期間調(diào)用了一定數(shù)量的斷言。這在測(cè)試異步代碼時(shí)通常很有用,以確?;卣{(diào)中的斷言確實(shí)被調(diào)用。

例如,假設(shè)我們有一個(gè)函數(shù)?doAsync?接收兩個(gè)回調(diào)?callback1?和?callback2?,它將以未知順序異步調(diào)用它們。我們可以用以下方法測(cè)試:

  1. test('doAsync calls both callbacks', () => {
  2. expect.assertions(2);
  3. function callback1(data) {
  4. expect(data).toBeTruthy();
  5. }
  6. function callback2(data) {
  7. expect(data).toBeTruthy();
  8. }
  9. doAsync(callback1, callback2);
  10. });

該?expect.assertions(2)?調(diào)用確保兩個(gè)回調(diào)都被實(shí)際調(diào)用。

expect.hasAssertions()

?expect.hasAssertions()?驗(yàn)證在測(cè)試期間至少調(diào)用了一個(gè)斷言。這在測(cè)試異步代碼時(shí)通常很有用,以確保回調(diào)中的斷言確實(shí)被調(diào)用。

例如,假設(shè)我們有一些處理狀態(tài)的函數(shù)。?prepareState?使用狀態(tài)對(duì)象調(diào)用回調(diào),?validateState?在該狀態(tài)對(duì)象上運(yùn)行,并?waitOnState?返回一個(gè)等待所有?prepareState?回調(diào)完成的承諾。我們可以用以下方法測(cè)試:

  1. test('prepareState prepares a valid state', () => {
  2. expect.hasAssertions();
  3. prepareState(state => {
  4. expect(validateState(state)).toBeTruthy();
  5. });
  6. return waitOnState();
  7. });

該?expect.hasAssertions()?調(diào)用確保?prepareState?回調(diào)實(shí)際被調(diào)用。

expect.not.arrayContaining(array)

?expect.not.arrayContaining(array)?匹配接收到的數(shù)組,該數(shù)組不包含預(yù)期數(shù)組中的所有元素。也就是說(shuō),預(yù)期數(shù)組不是接收數(shù)組的子集。

它是?expect.arrayContaining?的倒數(shù)??。

  1. describe('not.arrayContaining', () => {
  2. const expected = ['Samantha'];
  3. it('matches if the actual array does not contain the expected elements', () => {
  4. expect(['Alice', 'Bob', 'Eve']).toEqual(
  5. expect.not.arrayContaining(expected),
  6. );
  7. });
  8. });

expect.not.objectContaining(object)

?expect.not.objectContaining(object)?匹配任何不遞歸匹配預(yù)期屬性的接收對(duì)象。也就是說(shuō),預(yù)期對(duì)象不是接收對(duì)象的子集。因此,它匹配包含不在預(yù)期對(duì)象中的屬性的接收對(duì)象。

它是?expect.objectContaining的倒數(shù)?。

  1. describe('not.objectContaining', () => {
  2. const expected = {foo: 'bar'};
  3. it('matches if the actual object does not contain expected key: value pairs', () => {
  4. expect({bar: 'baz'}).toEqual(expect.not.objectContaining(expected));
  5. });
  6. });

expect.not.stringContaining(string)

?expect.not.stringContaining(string)? 如果它不是字符串或者它是一個(gè)不包含確切預(yù)期字符串的字符串,則匹配接收到的值。

它是?expect.stringContaining?的倒數(shù)??。

  1. describe('not.stringContaining', () => {
  2. const expected = 'Hello world!';
  3. it('matches if the received value does not contain the expected substring', () => {
  4. expect('How are you?').toEqual(expect.not.stringContaining(expected));
  5. });
  6. });

expect.not.stringMatching(string | regexp)

?expect.not.stringMatching(string | regexp)? 如果接收到的值不是字符串,或者它是與預(yù)期字符串或正則表達(dá)式不匹配的字符串,則匹配接收到的值。

它是?expect.stringMatching?的倒數(shù)。

  1. describe('not.stringMatching', () => {
  2. const expected = /Hello world!/;
  3. it('matches if the received value does not match the expected regex', () => {
  4. expect('How are you?').toEqual(expect.not.stringMatching(expected));
  5. });
  6. });

expect.objectContaining(object)

?expect.objectContaining(object)?匹配任何接收到的遞歸匹配預(yù)期屬性的對(duì)象。也就是說(shuō),預(yù)期對(duì)象是接收對(duì)象的子集。因此,它匹配包含存在于預(yù)期對(duì)象中的屬性的接收對(duì)象。

可以使用匹配器、 等?expect.anything()?,而不是預(yù)期對(duì)象中的文字屬性值。

例如,假設(shè)我們希望?onPress?用一個(gè)?Event?對(duì)象調(diào)用一個(gè)函數(shù),我們需要驗(yàn)證的是該事件是否具有?event.x?和?event.y?屬性。我們可以這樣做:

  1. test('onPress gets called with the right thing', () => {
  2. const onPress = jest.fn();
  3. simulatePresses(onPress);
  4. expect(onPress).toBeCalledWith(
  5. expect.objectContaining({
  6. x: expect.any(Number),
  7. y: expect.any(Number),
  8. }),
  9. );
  10. });

expect.stringContaining(string)

?expect.stringContaining(string)? 如果它是包含確切預(yù)期字符串的字符串,則匹配接收到的值。

expect.stringMatching(string | regexp)

?expect.stringMatching(string | regexp)? 如果它是與預(yù)期字符串或正則表達(dá)式匹配的字符串,則匹配接收到的值。

可以使用它代替文字值:

  • 在?toEqual?或?toBeCalledWith?
  • 匹配一個(gè)元素 ?arrayContaining?
  • 匹配?objectContaining?或?toMatchObject?

這個(gè)例子還展示了如何嵌套多個(gè)非對(duì)稱(chēng)匹配器,?expect.stringMatching?在?expect.arrayContaining?.

  1. describe('stringMatching in arrayContaining', () => {
  2. const expected = [
  3. expect.stringMatching(/^Alic/),
  4. expect.stringMatching(/^[BR]ob/),
  5. ];
  6. it('matches even if received contains additional elements', () => {
  7. expect(['Alicia', 'Roberto', 'Evelina']).toEqual(
  8. expect.arrayContaining(expected),
  9. );
  10. });
  11. it('does not match if received does not contain expected elements', () => {
  12. expect(['Roberto', 'Evelina']).not.toEqual(
  13. expect.arrayContaining(expected),
  14. );
  15. });
  16. });

expect.addSnapshotSerializer(serializer)

可以調(diào)用?expect.addSnapshotSerializer?以添加格式化應(yīng)用程序特定數(shù)據(jù)結(jié)構(gòu)的模塊。

對(duì)于單個(gè)測(cè)試文件,添加的模塊位于?snapshotSerializers?配置中的任何模塊之前,后者位于內(nèi)置 JavaScript 類(lèi)型和 React 元素的默認(rèn)快照序列化程序之前。添加的最后一個(gè)模塊是測(cè)試的第一個(gè)模塊。

  1. import serializer from 'my-serializer-module';
  2. expect.addSnapshotSerializer(serializer);
  3. // affects expect(value).toMatchSnapshot() assertions in the test file

如果在單個(gè)測(cè)試文件中添加快照序列化程序而不是將其添加到snapshotSerializers配置中:

  • 使依賴(lài)顯式而不是隱式。
  • 避免了可能導(dǎo)致從create-react-app 中彈出的配置限制。

有關(guān)更多信息,請(qǐng)參閱配置 Jest。

.not

如果你知道如何測(cè)試某樣?xùn)|西,?.not?讓你測(cè)試它的反面。例如,此代碼測(cè)試最好的 ?La Croix? 風(fēng)味不是椰子:

  1. test('the best flavor is not coconut', () => {
  2. expect(bestLaCroixFlavor()).not.toBe('coconut');
  3. });

.resolves

使用?.??resolves???解開(kāi)一個(gè)兌現(xiàn)承諾的價(jià)值,所以任何其他匹配可以鏈接。如果承諾被拒絕,則斷言失敗。

例如,此代碼測(cè)試 ?promise ?是否已解析并且結(jié)果值為?'lemon'?:

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

請(qǐng)注意,由于仍在測(cè)試 promise,因此測(cè)試仍然是異步的。因此,需要通過(guò)返回未包裝的斷言來(lái)告訴 Jest 等待

或者,可以?async?/?await?結(jié)合使用?.resolves?:

  1. test('resolves to lemon', async () => {
  2. await expect(Promise.resolve('lemon')).resolves.toBe('lemon');
  3. await expect(Promise.resolve('lemon')).resolves.not.toBe('octopus');
  4. });

.rejects

使用?.rejects?拆開(kāi)包裝,因此任何其他匹配可鏈接被拒絕承諾的理由。如果承諾被實(shí)現(xiàn),則斷言失敗。

例如,此代碼測(cè)試 ?Promise ?是否以 ?reason ?拒絕?'octopus'?:

  1. test('rejects to octopus', () => {
  2. // make sure to add a return statement
  3. return expect(Promise.reject(new Error('octopus'))).rejects.toThrow(
  4. 'octopus',
  5. );
  6. });

請(qǐng)注意,由于仍在測(cè)試 ?promise?,因此測(cè)試仍然是異步的。因此,需要通過(guò)返回未包裝的斷言來(lái)告訴 Jest 等待。

或者,可以?async?/?await?與?.rejects?.

  1. test('rejects to octopus', async () => {
  2. await expect(Promise.reject(new Error('octopus'))).rejects.toThrow('octopus');
  3. });

.toBe(value)

使用?.toBe?比較原始值或檢查對(duì)象實(shí)例的引用一致性。它調(diào)用?Object.is?比較值,這比?===?嚴(yán)格相等運(yùn)算符更適合測(cè)試。

例如,此代碼將驗(yàn)證?can?對(duì)象的某些屬性:

  1. const can = {
  2. name: 'pamplemousse',
  3. ounces: 12,
  4. };
  5. describe('the can', () => {
  6. test('has 12 ounces', () => {
  7. expect(can.ounces).toBe(12);
  8. });
  9. test('has a sophisticated name', () => {
  10. expect(can.name).toBe('pamplemousse');
  11. });
  12. });

不要?.toBe?與浮點(diǎn)數(shù)一起使用。例如,由于四舍五入,在 JavaScript0.2 + 0.1中并不嚴(yán)格等于0.3。如果有浮點(diǎn)數(shù),請(qǐng)嘗試?.toBeCloseTo?。

盡管?.toB?e匹配器檢查引用標(biāo)識(shí),但如果斷言失敗,它會(huì)報(bào)告值的深度比較。如果屬性之間的差異不能幫助你理解測(cè)試失敗的原因,尤其是在報(bào)告很大的情況下,那么你可以將比較移到?expect?函數(shù)中。例如,要斷言元素是否是同一個(gè)實(shí)例:

  • 重寫(xiě)?expect(received).toBe(expected)為expect(Object.is(received, expected)).toBe(true)?
  • 重寫(xiě)?expect(received).not.toBe(expected)為expect(Object.is(received, expected)).toBe(false)?

.toHaveBeenCalled()

同樣在別名下:? .toBeCalled()?

使用?.toHaveBeenCalled?以確保模擬功能得到調(diào)用。

例如,假設(shè)你有一個(gè)?drinkAll(drink, flavour)?函數(shù),它接受一個(gè)?drink?函數(shù)并將其應(yīng)用于所有可用的飲料。你可能想檢查是否??drink??調(diào)用了 ?for 'lemon'?,而不是 ?for 'octopus'?,因?yàn)?'octopus'?味道真的很奇怪,為什么會(huì)有章魚(yú)味的東西?你可以用這個(gè)測(cè)試套件做到這一點(diǎn):

  1. function drinkAll(callback, flavour) {
  2. if (flavour !== 'octopus') {
  3. callback(flavour);
  4. }
  5. }
  6. describe('drinkAll', () => {
  7. test('drinks something lemon-flavoured', () => {
  8. const drink = jest.fn();
  9. drinkAll(drink, 'lemon');
  10. expect(drink).toHaveBeenCalled();
  11. });
  12. test('does not drink something octopus-flavoured', () => {
  13. const drink = jest.fn();
  14. drinkAll(drink, 'octopus');
  15. expect(drink).not.toHaveBeenCalled();
  16. });
  17. });

.toHaveBeenCalledTimes(number)

同樣在別名下:? .toBeCalledTimes(number)?

使用?.toHaveBeenCalledTimes?以確保模擬功能得到調(diào)用次數(shù)確切數(shù)字。

例如,假設(shè)你有一個(gè)?drinkEach(drink, Array<flavor>)?函數(shù),drink?函數(shù)接受一個(gè)函數(shù)并將其應(yīng)用于傳遞的飲料數(shù)組。你可能想要檢查飲料函數(shù)被調(diào)用的確切次數(shù)。你可以用這個(gè)測(cè)試套件做到這一點(diǎn):

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

.toHaveBeenCalledWith(arg1, arg2, ...)

同樣在別名下:? .toBeCalledWith()?

使用?.toHaveBeenCalledWith?以確保模擬函數(shù)被調(diào)用的具體參數(shù)。

例如,假設(shè)你可以使用register函數(shù)注冊(cè)飲料,并且?applyToAll(f)?應(yīng)該將該函數(shù)f應(yīng)用于所有已注冊(cè)的飲料。為了確保這有效,你可以寫(xiě):

  1. test('registration applies correctly to orange La Croix', () => {
  2. const beverage = new LaCroix('orange');
  3. register(beverage);
  4. const f = jest.fn();
  5. applyToAll(f);
  6. expect(f).toHaveBeenCalledWith(beverage);
  7. });

.toHaveBeenLastCalledWith(arg1, arg2, ...)

同樣在別名下:? .lastCalledWith(arg1, arg2, ...)?

如果你有一個(gè)模擬函數(shù),你可以?.toHaveBeenLastCalledWith?用來(lái)測(cè)試它最后被調(diào)用的參數(shù)。例如,假設(shè)你有一個(gè)?applyToAllFlavors(f)?適用f于一系列風(fēng)味的函數(shù),并且你希望確保在調(diào)用它時(shí),它所操作的最后一種風(fēng)味是?'mango'?。你可以寫(xiě):

  1. test('applying to all flavors does mango last', () => {
  2. const drink = jest.fn();
  3. applyToAllFlavors(drink);
  4. expect(drink).toHaveBeenLastCalledWith('mango');
  5. });

.toHaveBeenNthCalledWith(nthCall, arg1, arg2, ....)

同樣在別名下:? .nthCalledWith(nthCall, arg1, arg2, ...)?

如果你有一個(gè)模擬函數(shù),你可以?.toHaveBeenNthCalledWith?用來(lái)測(cè)試它被調(diào)用的參數(shù)。例如,假設(shè)你有一個(gè)?drinkEach(drink, Array<flavor>)?適用?f?于一系列風(fēng)味的函數(shù),并且你希望確保在調(diào)用它時(shí),它操作的第一個(gè)風(fēng)味是?'lemon'?,而第二個(gè)是?'octopus'?。你可以寫(xiě):

  1. test('drinkEach drinks each drink', () => {
  2. const drink = jest.fn();
  3. drinkEach(drink, ['lemon', 'octopus']);
  4. expect(drink).toHaveBeenNthCalledWith(1, 'lemon');
  5. expect(drink).toHaveBeenNthCalledWith(2, 'octopus');
  6. });

注意:第 n 個(gè)參數(shù)必須是從 1 開(kāi)始的正整數(shù)。

.toHaveReturned()

同樣在別名下:? .toReturn()?

如果你有一個(gè)模擬函數(shù),你可以?.toHaveReturned?用來(lái)測(cè)試模擬函數(shù)是否成功返回(即沒(méi)有拋出錯(cuò)誤)至少一次。例如,假設(shè)你有一個(gè)?drink?返回?true?. 你可以寫(xiě):

  1. test('drinks returns', () => {
  2. const drink = jest.fn(() => true);
  3. drink();
  4. expect(drink).toHaveReturned();
  5. });

.toHaveReturnedTimes(number)

同樣在別名下:? .toReturnTimes(number)?

使用?.toHaveReturnedTimes?以確保模擬函數(shù)返回成功(即未引發(fā)錯(cuò)誤)的次一個(gè)確切的數(shù)字。任何拋出錯(cuò)誤的模擬函數(shù)調(diào)用都不會(huì)計(jì)入函數(shù)返回的次數(shù)。

例如,假設(shè)你有一個(gè)?drink?返回?true?. 你可以寫(xiě):

  1. test('drink returns twice', () => {
  2. const drink = jest.fn(() => true);
  3. drink();
  4. drink();
  5. expect(drink).toHaveReturnedTimes(2);
  6. });

.toHaveReturnedWith(value)

同樣在別名下: ?.toReturnWith(value)?

使用?.toHaveReturnedWith?以確保模擬函數(shù)返回的特定值。

例如,假設(shè)你有一個(gè)?drink?返回已消費(fèi)飲料名稱(chēng)的模擬。你可以寫(xiě):

  1. test('drink returns La Croix', () => {
  2. const beverage = {name: 'La Croix'};
  3. const drink = jest.fn(beverage => beverage.name);
  4. drink(beverage);
  5. expect(drink).toHaveReturnedWith('La Croix');
  6. });

.toHaveLastReturnedWith(value)

同樣在別名下:? .lastReturnedWith(value)?

使用?.toHaveLastReturnedWith?來(lái)測(cè)試一個(gè)模擬函數(shù)的最后一個(gè)返回的特定值。如果對(duì)模擬函數(shù)的最后一次調(diào)用拋出錯(cuò)誤,則無(wú)論提供什么值作為預(yù)期返回值,此匹配器都將失敗。

例如,假設(shè)你有一個(gè)?drink?返回已消費(fèi)飲料名稱(chēng)的模擬。你可以寫(xiě):

  1. test('drink returns La Croix (Orange) last', () => {
  2. const beverage1 = {name: 'La Croix (Lemon)'};
  3. const beverage2 = {name: 'La Croix (Orange)'};
  4. const drink = jest.fn(beverage => beverage.name);
  5. drink(beverage1);
  6. drink(beverage2);
  7. expect(drink).toHaveLastReturnedWith('La Croix (Orange)');
  8. });

.toHaveNthReturnedWith(nthCall, value)

同樣在別名下:? .nthReturnedWith(nthCall, value)?

使用?.toHaveNthReturnedWith?測(cè)試,對(duì)于第?n?個(gè)調(diào)用返回一個(gè)模擬功能的具體價(jià)值。如果對(duì)模擬函數(shù)的第 ?n ?次調(diào)用拋出錯(cuò)誤,則無(wú)論你提供什么值作為預(yù)期返回值,此匹配器都將失敗。

例如,假設(shè)你有一個(gè)?drink?返回已消費(fèi)飲料名稱(chēng)的模擬。你可以寫(xiě):

  1. test('drink returns expected nth calls', () => {
  2. const beverage1 = {name: 'La Croix (Lemon)'};
  3. const beverage2 = {name: 'La Croix (Orange)'};
  4. const drink = jest.fn(beverage => beverage.name);
  5. drink(beverage1);
  6. drink(beverage2);
  7. expect(drink).toHaveNthReturnedWith(1, 'La Croix (Lemon)');
  8. expect(drink).toHaveNthReturnedWith(2, 'La Croix (Orange)');
  9. });

注意:第 n 個(gè)參數(shù)必須是從 1 開(kāi)始的正整數(shù)。

.toHaveLength(number)

使用?.toHaveLength?檢查的對(duì)象有一個(gè)?.length?屬性,并將其設(shè)置為某一數(shù)值。

這對(duì)于檢查數(shù)組或字符串大小特別有用。

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

.toHaveProperty(keyPath, value?)

使用?.toHaveProperty?檢查,如果在提供的參考屬性?keyPath?存在的對(duì)象。為了檢查對(duì)象中深度嵌套的屬性,你可以使用點(diǎn)表示法或包含用于深度引用的 ?keyPath ?的數(shù)組。

你可以提供一個(gè)可選?value?參數(shù)來(lái)比較接收到的屬性值(遞歸地用于對(duì)象實(shí)例的所有屬性,也稱(chēng)為深度相等,如?toEqual?匹配器)。

以下示例包含?houseForSale?具有嵌套屬性的對(duì)象。我們?toHaveProperty?用來(lái)檢查對(duì)象中各種屬性的存在和值。

  1. // Object containing house features to be tested
  2. const houseForSale = {
  3. bath: true,
  4. bedrooms: 4,
  5. kitchen: {
  6. amenities: ['oven', 'stove', 'washer'],
  7. area: 20,
  8. wallColor: 'white',
  9. 'nice.oven': true,
  10. },
  11. 'ceiling.height': 2,
  12. };
  13. test('this house has my desired features', () => {
  14. // Example Referencing
  15. expect(houseForSale).toHaveProperty('bath');
  16. expect(houseForSale).toHaveProperty('bedrooms', 4);
  17. expect(houseForSale).not.toHaveProperty('pool');
  18. // Deep referencing using dot notation
  19. expect(houseForSale).toHaveProperty('kitchen.area', 20);
  20. expect(houseForSale).toHaveProperty('kitchen.amenities', [
  21. 'oven',
  22. 'stove',
  23. 'washer',
  24. ]);
  25. expect(houseForSale).not.toHaveProperty('kitchen.open');
  26. // Deep referencing using an array containing the keyPath
  27. expect(houseForSale).toHaveProperty(['kitchen', 'area'], 20);
  28. expect(houseForSale).toHaveProperty(
  29. ['kitchen', 'amenities'],
  30. ['oven', 'stove', 'washer'],
  31. );
  32. expect(houseForSale).toHaveProperty(['kitchen', 'amenities', 0], 'oven');
  33. expect(houseForSale).toHaveProperty(['kitchen', 'nice.oven']);
  34. expect(houseForSale).not.toHaveProperty(['kitchen', 'open']);
  35. // Referencing keys with dot in the key itself
  36. expect(houseForSale).toHaveProperty(['ceiling.height'], 'tall');
  37. });

.toBeCloseTo(number, numDigits?)

使用?toBeCloseTo?浮點(diǎn)數(shù)的近似相等比較。

可選?numDigits?參數(shù)限制小數(shù)點(diǎn)后要檢查的位數(shù)。對(duì)于默認(rèn)值2,測(cè)試標(biāo)準(zhǔn)是?Math.abs(expected - received) < 0.005(即10 ** -2 / 2)?。

直觀(guān)的相等比較經(jīng)常失敗,因?yàn)槭M(jìn)制(基數(shù) 10)值的算術(shù)通常在有限精度的二進(jìn)制(基數(shù) 2)表示中存在舍入誤差。例如,此測(cè)試失?。?/p>

  1. test('adding works sanely with decimals', () => {
  2. expect(0.2 + 0.1).toBe(0.3); // Fails!
  3. });

它失敗了,因?yàn)樵?JavaScript 中,0.2 + 0.1實(shí)際上是0.30000000000000004.

例如,此測(cè)試以 5 位數(shù)的精度通過(guò):

  1. test('adding works sanely with decimals', () => {
  2. expect(0.2 + 0.1).toBeCloseTo(0.3, 5);
  3. });

因?yàn)楦↑c(diǎn)錯(cuò)誤是要?toBeCloseTo?解決的問(wèn)題,所以它不支持大整數(shù)值。

.toBeDefined()

使用?.toBeDefined?檢查一個(gè)變量是不是不確定的。例如,如果你想檢查一個(gè)函數(shù)是否?fetchNewFlavorIdea()?返回了一些東西,你可以這樣寫(xiě):

  1. test('there is a new flavor idea', () => {
  2. expect(fetchNewFlavorIdea()).toBeDefined();
  3. });

可以編寫(xiě)?expect(fetchNewFlavorIdea()).not.toBe(undefined)?,但最好避免undefined在代碼中直接引用。

.toBeFalsy()

使用?.toBeFalsy?時(shí),你不關(guān)心的值是什么,你要確保一個(gè)值是在布爾上下文假的。例如,假設(shè)你有一些如下所示的應(yīng)用程序代碼:

  1. drinkSomeLaCroix();
  2. if (!getErrors()) {
  3. drinkMoreLaCroix();
  4. }

你可能并不關(guān)心?getErrors?返回什么,特別是 - 它可能返回?false?、?null?、 或?0?,而你的代碼仍然可以工作。所以如果你想在喝了一些 La Croix 后測(cè)試有沒(méi)有錯(cuò)誤,你可以寫(xiě):

  1. test('drinking La Croix does not lead to errors', () => {
  2. drinkSomeLaCroix();
  3. expect(getErrors()).toBeFalsy();
  4. });

在JavaScript中,有六個(gè)falsy值:false,0,'',null,undefined,和NaN。其他一切都是真實(shí)的。

.toBeGreaterThan(number | bigint)

用?toBeGreaterThan?比較?received ?> ?expected?的數(shù)量或大整數(shù)值。例如,?ouncesPerCan()?返回值大于 10 盎司的測(cè)試:

  1. test('ounces per can is more than 10', () => {
  2. expect(ouncesPerCan()).toBeGreaterThan(10);
  3. });

.toBeGreaterThanOrEqual(number | bigint)

用?toBeGreaterThanOrEqual?比較?received ?>= ?expected?的數(shù)量或大整數(shù)值。例如,?ouncesPerCan()?返回至少 12 盎司值的測(cè)試:

  1. test('ounces per can is at least 12', () => {
  2. expect(ouncesPerCan()).toBeGreaterThanOrEqual(12);
  3. });

.toBeLessThan(number | bigint)

用?toBeLessThan?比較?received ?< ?expected?的數(shù)量或大整數(shù)值。例如,?ouncesPerCan()?返回小于 20 盎司值的測(cè)試:

  1. test('ounces per can is less than 20', () => {
  2. expect(ouncesPerCan()).toBeLessThan(20);
  3. });

.toBeLessThanOrEqual(number | bigint)

用?toBeLessThanOrEqual?比較?received ?<= ?expected?的數(shù)量或大整數(shù)值。例如,測(cè)試?ouncesPerCan()?最多返回 12 盎司的值:

  1. test('ounces per can is at most 12', () => {
  2. expect(ouncesPerCan()).toBeLessThanOrEqual(12);
  3. });

.toBeInstanceOf(Class)

使用?.toBeInstanceOf(Class)?檢查對(duì)象是一個(gè)類(lèi)的實(shí)例。這個(gè)匹配器?instanceof?在下面使用。

  1. class A {}
  2. expect(new A()).toBeInstanceOf(A);
  3. expect(() => {}).toBeInstanceOf(Function);
  4. expect(new A()).toBeInstanceOf(Function); // throws

.toBeNull()

.?toBeNull()?與相同?.toBe(null)?但錯(cuò)誤消息更好一些。所以?.toBeNull()?當(dāng)你想檢查某些東西是否為空時(shí)使用。

  1. function bloop() {
  2. return null;
  3. }
  4. test('bloop returns null', () => {
  5. expect(bloop()).toBeNull();
  6. });

.toBeTruthy()

使用?.toBeTruthy?時(shí),你不關(guān)心的值是什么,你要確保一個(gè)值在布爾環(huán)境是真實(shí)的。例如,假設(shè)你有一些如下所示的應(yīng)用程序代碼:

  1. drinkSomeLaCroix();
  2. if (thirstInfo()) {
  3. drinkMoreLaCroix();
  4. }

你可能不在乎?thirstInfo?返回什么,?特別是?它可能返回true或者一個(gè)復(fù)雜的對(duì)象,并且你的代碼仍然可以工作。所以如果你想測(cè)試在喝了一些 ?La Croix? 后?thirstInfo?是否真實(shí),你可以寫(xiě):

  1. test('drinking La Croix leads to having thirst info', () => {
  2. drinkSomeLaCroix();
  3. expect(thirstInfo()).toBeTruthy();
  4. });

在JavaScript中,有六個(gè)falsy值:?false?,?0?,?''?,?null?,?undefined?,和?NaN?。其他一切都是真實(shí)的。

.toBeUndefined()

使用?.toBeUndefined?檢查變量不確定。例如,如果你想檢查一個(gè)函數(shù)?bestDrinkForFlavor(flavor)?返回?undefined?的?'octopus'?味道,因?yàn)闆](méi)有好的?octopus-flavored?飲料:

  1. test('the best drink for octopus flavor is undefined', () => {
  2. expect(bestDrinkForFlavor('octopus')).toBeUndefined();
  3. });

你可以編寫(xiě)?expect(bestDrinkForFlavor('octopus')).toBe(undefined)?,但最好避免?undefined?在代碼中直接引用。

.toBeNaN()

?.toBeNaN?在檢查值時(shí)使用?NaN?。

  1. test('passes when value is NaN', () => {
  2. expect(NaN).toBeNaN();
  3. expect(1).not.toBeNaN();
  4. });

.toContain(item)

使用?.toContain?時(shí)要檢查的項(xiàng)目是在數(shù)組中。為了測(cè)試數(shù)組中的項(xiàng)目,這使用?===?了嚴(yán)格的相等性檢查。.toContain還可以檢查一個(gè)字符串是否是另一個(gè)字符串的子字符串。

例如,如果?getAllFlavors()?返回一個(gè)風(fēng)味數(shù)組,并且你想確保其中包含該數(shù)組,?lime?則可以編寫(xiě):

  1. test('the flavor list contains lime', () => {
  2. expect(getAllFlavors()).toContain('lime');
  3. });

.toContainEqual(item)

使用?.toContainEqual?時(shí)要檢查是否具有特定結(jié)構(gòu)和值的項(xiàng)目包含在一個(gè)陣列。為了測(cè)試數(shù)組中的項(xiàng)目,這個(gè)匹配器遞歸地檢查所有字段的相等性,而不是檢查對(duì)象身份。

  1. describe('my beverage', () => {
  2. test('is delicious and not sour', () => {
  3. const myBeverage = {delicious: true, sour: false};
  4. expect(myBeverages()).toContainEqual(myBeverage);
  5. });
  6. });

.toEqual(value)

用于?.toEqual?遞歸比較對(duì)象實(shí)例的所有屬性(也稱(chēng)為“深度”相等)。它調(diào)用Object.is比較原始值,這比?===?嚴(yán)格相等運(yùn)算符更適合測(cè)試。

例如,?.toEqual?和?.toBe?不同的表現(xiàn)在這個(gè)測(cè)試套件,所以所有的測(cè)試都通過(guò)了:

  1. const can1 = {
  2. flavor: 'grapefruit',
  3. ounces: 12,
  4. };
  5. const can2 = {
  6. flavor: 'grapefruit',
  7. ounces: 12,
  8. };
  9. describe('the La Croix cans on my desk', () => {
  10. test('have all the same properties', () => {
  11. expect(can1).toEqual(can2);
  12. });
  13. test('are not the exact same can', () => {
  14. expect(can1).not.toBe(can2);
  15. });
  16. });
注意:?.toEqual?不會(huì)對(duì)兩個(gè)錯(cuò)誤執(zhí)行深度相等檢查。僅?message?考慮 ?Error?的屬性是否相等。建議使用?.toThrow?匹配器進(jìn)行錯(cuò)誤測(cè)試。

如果屬性之間的差異不能幫助你理解測(cè)試失敗的原因,尤其是在報(bào)告很大的情況下,那么你可以將比較移到expect函數(shù)中。例如,使用類(lèi)的?equals?方法?Buffer?來(lái)斷言緩沖區(qū)是否包含相同的內(nèi)容:

  • 重寫(xiě)?expect(received).toEqual(expected)為expect(received.equals(expected)).toBe(true)?
  • 重寫(xiě)?expect(received).not.toEqual(expected)為expect(received.equals(expected)).toBe(false)?

.toMatch(regexpOrString)

使用?.toMatch?檢查字符串中的正則表達(dá)式匹配。

例如,你可能不知道究竟?essayOnTheBestFlavor()?返回什么,但你知道它是一個(gè)非常長(zhǎng)的字符串,并且子字符串?grapefruit?應(yīng)該在某個(gè)地方??梢允褂靡韵路椒ㄟM(jìn)行測(cè)試:

  1. describe('an essay on the best flavor', () => {
  2. test('mentions grapefruit', () => {
  3. expect(essayOnTheBestFlavor()).toMatch(/grapefruit/);
  4. expect(essayOnTheBestFlavor()).toMatch(new RegExp('grapefruit'));
  5. });
  6. });

這個(gè)匹配器還接受一個(gè)字符串,它將嘗試匹配:

  1. describe('grapefruits are healthy', () => {
  2. test('grapefruits are a fruit', () => {
  3. expect('grapefruits').toMatch('fruit');
  4. });
  5. });

.toMatchObject(object)

使用?.toMatchObject?檢查JavaScript對(duì)象對(duì)象的屬性的子集相匹配。它會(huì)將接收到的對(duì)象與不在預(yù)期對(duì)象中的屬性進(jìn)行匹配。

還可以傳遞一個(gè)對(duì)象數(shù)組,在這種情況下,只有當(dāng)接收到的數(shù)組中的每個(gè)對(duì)象都匹配(在上述toMatchObject意義上)預(yù)期數(shù)組中的相應(yīng)對(duì)象時(shí),該方法才會(huì)返回 ?true ?。如果你想檢查兩個(gè)數(shù)組的元素?cái)?shù)量是否匹配,這很有用,而不是?arrayContaining?允許接收數(shù)組中的額外元素。

可以將屬性與值或匹配器進(jìn)行匹配。

  1. const houseForSale = {
  2. bath: true,
  3. bedrooms: 4,
  4. kitchen: {
  5. amenities: ['oven', 'stove', 'washer'],
  6. area: 20,
  7. wallColor: 'white',
  8. },
  9. };
  10. const desiredHouse = {
  11. bath: true,
  12. kitchen: {
  13. amenities: ['oven', 'stove', 'washer'],
  14. wallColor: expect.stringMatching(/white|yellow/),
  15. },
  16. };
  17. test('the house has my desired features', () => {
  18. expect(houseForSale).toMatchObject(desiredHouse);
  19. });
  1. describe('toMatchObject applied to arrays', () => {
  2. test('the number of elements must match exactly', () => {
  3. expect([{foo: 'bar'}, {baz: 1}]).toMatchObject([{foo: 'bar'}, {baz: 1}]);
  4. });
  5. test('.toMatchObject is called for each elements, so extra object properties are okay', () => {
  6. expect([{foo: 'bar'}, {baz: 1, extra: 'quux'}]).toMatchObject([
  7. {foo: 'bar'},
  8. {baz: 1},
  9. ]);
  10. });
  11. });

.toMatchSnapshot(propertyMatchers?, hint?)

這可確保值與最近的快照相匹配。查看快照測(cè)試指南了解更多信息。

可以提供一個(gè)可選的?propertyMatchers?對(duì)象參數(shù),如果接收的值是對(duì)象實(shí)例,則該參數(shù)具有不對(duì)稱(chēng)匹配器作為預(yù)期屬性子集的值。這就像?toMatchObject?對(duì)屬性的子集使用靈活的標(biāo)準(zhǔn),然后是快照測(cè)試作為其余屬性的精確標(biāo)準(zhǔn)。

可以提供?hint?附加到測(cè)試名稱(chēng)的可選字符串參數(shù)。盡管 Jest 總是在快照名稱(chēng)的末尾附加一個(gè)數(shù)字,但在區(qū)分單個(gè)或塊中的多個(gè)快照時(shí),簡(jiǎn)短的描述性提示可能比數(shù)字更有用。Jest 在相應(yīng)文件中按名稱(chēng)對(duì)快照進(jìn)行排序。 ?ittest.snap?

.toMatchInlineSnapshot(propertyMatchers?, inlineSnapshot)

確保值與最近的快照相匹配。

可以提供一個(gè)可選的?propertyMatchers?對(duì)象參數(shù),如果接收的值是對(duì)象實(shí)例,則該參數(shù)具有不對(duì)稱(chēng)匹配器作為預(yù)期屬性子集的值。這就像?toMatchObject?對(duì)屬性的子集使用靈活的標(biāo)準(zhǔn),然后是快照測(cè)試作為其余屬性的精確標(biāo)準(zhǔn)。

Jest在第一次運(yùn)行測(cè)試時(shí)將?inlineSnapshot?字符串參數(shù)添加到測(cè)試文件(而不是外部?.snap?文件)中的匹配器。

查看內(nèi)聯(lián)快照部分了解更多信息。

.toStrictEqual(value)

使用?.toStrictEqual?測(cè)試的對(duì)象具有相同的類(lèi)型以及結(jié)構(gòu)。

與以下的區(qū)別?.toEqual?:

  • undefined檢查具有屬性的鍵。例如,使用時(shí)?{a: undefined, b: 2}?不匹配。?{b: 2}.toStrictEqual?
  • 檢查數(shù)組稀疏性。例如,使用時(shí)?[, 1]?不匹配。?[undefined, 1].toStrictEqual?
  • 檢查對(duì)象類(lèi)型是否相等。例如,具有字段?a?和的類(lèi)實(shí)例?b?將不等于具有字段?a?和的文字對(duì)象?b?。
  1. class LaCroix {
  2. constructor(flavor) {
  3. this.flavor = flavor;
  4. }
  5. }
  6. describe('the La Croix cans on my desk', () => {
  7. test('are not semantically the same', () => {
  8. expect(new LaCroix('lemon')).toEqual({flavor: 'lemon'});
  9. expect(new LaCroix('lemon')).not.toStrictEqual({flavor: 'lemon'});
  10. });
  11. });

.toThrow(error?)

同樣在別名下:? .toThrowError(error?)?

使用?.toThrow?測(cè)試,當(dāng)它被稱(chēng)為函數(shù)拋出。例如,如果我們要測(cè)試?drinkFlavor('octopus')?投擲,因?yàn)檎卖~(yú)的味道太難喝了,我們可以這樣寫(xiě):

  1. test('throws on octopus', () => {
  2. expect(() => {
  3. drinkFlavor('octopus');
  4. }).toThrow();
  5. });
注意:必須將代碼包裹在一個(gè)函數(shù)中,否則無(wú)法捕獲錯(cuò)誤,斷言失敗。

可以提供一個(gè)可選參數(shù)來(lái)測(cè)試是否拋出了特定錯(cuò)誤:

  • 正則表達(dá)式:錯(cuò)誤消息與模式匹配
  • 字符串:錯(cuò)誤消息包括子字符串
  • 錯(cuò)誤對(duì)象:錯(cuò)誤消息等于對(duì)象的消息屬性
  • 錯(cuò)誤類(lèi):錯(cuò)誤對(duì)象是類(lèi)的實(shí)例

例如,假設(shè)它?drinkFlavor?是這樣編碼的:

  1. function drinkFlavor(flavor) {
  2. if (flavor == 'octopus') {
  3. throw new DisgustingFlavorError('yuck, octopus flavor');
  4. }
  5. // Do some other stuff
  6. }

我們可以通過(guò)幾種方式測(cè)試這個(gè)錯(cuò)誤是否被拋出:

  1. test('throws on octopus', () => {
  2. function drinkOctopus() {
  3. drinkFlavor('octopus');
  4. }
  5. // Test that the error message says "yuck" somewhere: these are equivalent
  6. expect(drinkOctopus).toThrowError(/yuck/);
  7. expect(drinkOctopus).toThrowError('yuck');
  8. // Test the exact error message
  9. expect(drinkOctopus).toThrowError(/^yuck, octopus flavor$/);
  10. expect(drinkOctopus).toThrowError(new Error('yuck, octopus flavor'));
  11. // Test that we get a DisgustingFlavorError
  12. expect(drinkOctopus).toThrowError(DisgustingFlavorError);
  13. });

.toThrowErrorMatchingSnapshot(hint?)

使用?.toThrowErrorMatchingSnapshot?測(cè)試一個(gè)函數(shù)拋出匹配最新的快照時(shí),它被稱(chēng)為一個(gè)錯(cuò)誤。

可以提供hint附加到測(cè)試名稱(chēng)的可選字符串參數(shù)。盡管 Jest 總是在快照名稱(chēng)的末尾附加一個(gè)數(shù)字,但在區(qū)分單個(gè)或塊中的多個(gè)快照時(shí),簡(jiǎn)短的描述性提示可能比數(shù)字更有用。Jest 在相應(yīng)文件中按名稱(chēng)對(duì)快照進(jìn)行排序。 ittest.snap

例如,假設(shè)你有一個(gè)?drinkFlavor?函數(shù),該函數(shù)在風(fēng)味為 時(shí)拋出?'octopus'?,其編碼如下:

  1. function drinkFlavor(flavor) {
  2. if (flavor == 'octopus') {
  3. throw new DisgustingFlavorError('yuck, octopus flavor');
  4. }
  5. // Do some other stuff
  6. }

此函數(shù)的測(cè)試將如下所示:

  1. test('throws on octopus', () => {
  2. function drinkOctopus() {
  3. drinkFlavor('octopus');
  4. }
  5. expect(drinkOctopus).toThrowErrorMatchingSnapshot();
  6. });

它將生成以下快照:

  1. exports[`drinking flavors throws on octopus 1`] = `"yuck, octopus flavor"`;

查看React Tree Snapshot Testing以獲取有關(guān)快照測(cè)試的更多信息。

.toThrowErrorMatchingInlineSnapshot(inlineSnapshot)

使用?.toThrowErrorMatchingInlineSnapshot?測(cè)試一個(gè)函數(shù)拋出匹配最新的快照時(shí),它被稱(chēng)為一個(gè)錯(cuò)誤。

Jest在第一次運(yùn)行測(cè)試時(shí)將?inlineSnapshot?字符串參數(shù)添加到測(cè)試文件(而不是外部?.snap?文件)中的匹配器。

查看內(nèi)聯(lián)快照部分了解更多信息。


以上內(nèi)容是否對(duì)您有幫助:
在線(xiàn)筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)