Expect
Quando você está escrevendo testes, muitas das vezes você precisa checar se os valores satisfazem certas condições. expect
lhe dá acesso a inúmeros "matchers" que permitem validar diferentes coisas.
Métodos #
Referência #
expect(value)
#
A função expect
é usada toda vez que você quer testar um valor. Você raramente irá usar o expect
sozinho. Em vez disso, você irá usar expect
junto com uma função "matcher" para verificar algo sobre um valor.
É mais fácil de entender isto com um exemplo. Digamos que você tenha um método bestLaCroixFlavor()
que se espera retornar a string 'grapefruit'
. Veja como você testaria isso:
test('the best flavor is grapefruit', () => { expect(bestLaCroixFlavor()).toBe('grapefruit'); });
Neste caso, toBe
é a função "matcher". Existem muitas funções "matcher" diferentes, documentadas abaixo, para ajuda-lo a testar coisas diferentes.
O argumento para expect
deve ser o valor que o seu código produz, e qualquer argumento para o matcher deve ser o valor correto esperado. Se você misturá-los, os testes ainda irão funcionar, mas as mensagens de erro em testes que falharem vão parecer estranhas.
expect.extend(matchers)
#
Você pode usar expect.extend
para adicionar seus próprios "matchers" em Jest. Por exemplo, digamos que você está testando uma biblioteca de teoria de números e que frequentemente está verificando que os números são divisíveis por outros números. Você poderia abstrair isso em um "matcher" toBeDivisibleBy
:
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); });
Matchers devem retornar um objeto com duas chaves. pass
indica se houve ou não uma correspondência, e message
fornece uma função sem argumentos que retorna uma mensagem de erro em caso de falha. Assim, quando pass
é falso, message
deve retornar a mensagem de erro quando expect(x).yourMatcher()
falha. E quando pass
é verdadeiro, a mensagem
deve retornar a mensagem de erro quando expect(x).not.yourMatcher()
falha.
Essas funções auxiliares podem ser encontradas em this
dentro de um "matcher" personalizado:
this.isNot
#
Um valor booleano para que você saiba que este "matcher" foi chamado com o modificador negado .not
permitindo você inverter sua verificação.
this.equals(a, b)
#
Esta é uma função de igualdade profunda que retornará true
se dois objetos têm os mesmos valores (recursivamente).
this.utils
#
Há uma série de ferramentas úteis expostas em this.utils
consistindo principalmente das exportações de jest-matcher-utils
.
Os mais úteis são matcherHint
, printExpected
e printReceived
para formatar bem as mensagens de erro. Por exemplo, dê uma olhada na implementação para o "matcher" toBe
:
const diff = require('jest-diff'); expect.extend({ toBe(received, expected) { const pass = received === expected; const message = pass ? () => this.utils.matcherHint('.not.toBe') + '\n\n' + `Expected value to not be (using ===):\n` + ` ${this.utils.printExpected(expected)}\n` + `Received:\n` + ` ${this.utils.printReceived(received)}` : () => { const diffString = diff(expected, received, { expand: this.expand, }); return this.utils.matcherHint('.toBe') + '\n\n' + `Expected value to be (using ===):\n` + ` ${this.utils.printExpected(expected)}\n` + `Received:\n` + ` ${this.utils.printReceived(received)}` + (diffString ? `\n\nDifference:\n\n${diffString}` : ''); }; return {actual: received, message, pass}; }, });
Isto imprimirá algo como isto:
expect(received).toBe(expected) Expected value to be (using ===): "banana" Received: "apple"
Quando uma verificação falha, a mensagem de erro deve dar o máximo de informação necessária para o usuário, para que eles possam resolver seu problema rapidamente. Você deve criar uma mensagem de falha precisa para certificar-se de que os usuários de suas verificações personalizados tenham uma boa experiência de desenvolvimento.
expect.anything()
#
expect.anything()
corresponde a qualquer coisa menos null
ou undefined
. Você pode usá-lo dentro de toEqual
ou toBeCalledWith
em vez de um valor literal. Por exemplo, se você quiser verificar que uma função de simulação (mock, em inglês) é chamada com um argumento não nulo:
test('map calls its argument with a non-null argument', () => { const mock = jest.fn(); [1].map(mock); expect(mock).toBeCalledWith(expect.anything()); });
expect.any(constructor)
#
expect.any(constructor)
corresponde a qualquer coisa que foi criada com o construtor fornecido. Você pode usá-lo dentro de toEqual
ou toBeCalledWith
em vez de um valor literal. Por exemplo, se você quiser verificar que uma função de simulação (mock, em inglês) é chamada com um número:
function randocall(fn) { return fn(Math.floor(Math.random() * 6 + 1)); } test('randocall calls its callback with a number', () => { const mock = jest.fn(); randocall(mock); expect(mock).toBeCalledWith(expect.any(Number)); });
expect.arrayContaining(array)
#
expect.arrayContaining(array)
corresponde a um array recebido que contém todos os elementos no array esperado. Ou seja, o array esperado é um subconjunto do array recebido. Portanto, combina com um array recebido que contém elementos que não estão no array esperado.
Você pode usá-lo em vez de um valor literal:
- em
toEqual
outoBeCalledWith
- para corresponder a uma propriedade em
objectContaining
outoMatchObject
describe('arrayContaining', () => { const expected = ['Alice', 'Bob']; it('matches even if received contains additional elements', () => { expect(['Alice', 'Bob', 'Eve']).toEqual(expect.arrayContaining(expected)); }); it('does not match if received does not contain expected elements', () => { expect(['Bob', 'Eve']).not.toEqual(expect.arrayContaining(expected)); }); });
describe('Beware of a misunderstanding! A sequence of dice rolls', () => { const expected = [1, 2, 3, 4, 5, 6]; it('matches even with an unexpected number 7', () => { expect([4, 1, 6, 7, 3, 5, 2, 5, 4, 6]) .toEqual(expect.arrayContaining(expected)); }); it('does not match without an expected number 2', () => { expect([4, 1, 6, 7, 3, 5, 7, 5, 4, 6]) .not.toEqual(expect.arrayContaining(expected)); }); });
expect.assertions(number)
#
expect.assertions(number)
verifica que um certo número de verificações são chamadas durante um teste. Isto é frequentemente útil ao testar código assíncrono, a fim de certificar-se que as verificações de um "callback" realmente tenham sido chamadas.
Por exemplo, digamos que temos uma função doAsync
que recebe duas "callbacks" callback1
e callback2
, de forma assíncrona chamará as duas numa ordem desconhecida. Podemos testar isso com:
test('doAsync calls both callbacks', () => { expect.assertions(2); function callback1(data) { expect(data).toBeTruthy(); } function callback2(data) { expect(data).toBeTruthy(); } doAsync(callback1, callback2); });
A chamada expect.assertions(2)
garante que as duas "callbacks" sejam realmente chamadas.
expect.hasAssertions()
#
expect.hasAssertions()
verifica que pelo menos uma verificação é chamada durante um teste. Isto é frequentemente útil ao testar código assíncrono, a fim de certificar-se que as verificações de um "callback" realmente tenham sido chamadas.
Por exemplo, digamos que nós temos algumas funções onde todas lidam com estado. prepareState
chama um "callback" com um objeto de estado, validateState
é executado nesse objeto de estado, e waitOnState
retorna uma promessa que aguarda até que todas as "callbacks" prepareState
completem. Podemos testar isso com:
test('prepareState prepares a valid state', () => { expect.hasAssertions(); prepareState(state => { expect(validateState(state)).toBeTruthy(); }); return waitOnState(); });
A chamada expect.hasAssertions()
garante que a "callback" prepareState
é realmente chamada.
expect.objectContaining(object)
#
expect.objectContaining(object)
corresponde a qualquer objeto recebido que recursivamente coincide com as propriedades esperadas. Ou seja, o objeto esperado é um subconjunto do objeto recebido. Portanto, combina com um objeto recebido que contém propriedades que não estão no objeto esperado.
Em vez de valores literais de propriedade no objeto esperado, você pode usar "matchers", expect.anything()
, e assim por diante.
Por exemplo, digamos que esperamos uma função onPress
ser chamada com um objeto Event
, e tudo que precisamos verificar é que o evento tem propriedades event.x
e event.y
. Podemos fazer isso com:
test('onPress gets called with the right thing', () => { const onPress = jest.fn(); simulatePresses(onPress); expect(onPress).toBeCalledWith(expect.objectContaining({ x: expect.any(Number), y: expect.any(Number), })); });
expect.stringContaining(string)
#
disponível no Jest 19.0.0+ #
expect.stringContaining(string)
corresponde a qualquer string recebida que contém a exata string esperada.
expect.stringMatching(regexp)
#
expect.stringMatching(regexp)
corresponde a qualquer string recebida que coincide com o regexp esperado.
Você pode usá-lo em vez de um valor literal:
- em
toEqual
outoBeCalledWith
- para corresponder a um elemento em
arrayContaining
- para corresponder a uma propriedade em
objectContaining
outoMatchObject
Este exemplo também mostra como você pode aninhar vários "matchers" assimétricos, com expect.stringMatching
dentro de expect.arrayContaining
.
describe('stringMatching in arrayContaining', () => { const expected = [ expect.stringMatching(/^Alic/), expect.stringMatching(/^[BR]ob/), ]; it('matches even if received contains additional elements', () => { expect(['Alicia', 'Roberto', 'Evelina']) .toEqual(expect.arrayContaining(expected)); }); it('does not match if received does not contain expected elements', () => { expect(['Roberto', 'Evelina']) .not.toEqual(expect.arrayContaining(expected)); }); });
expect.addSnapshotSerializer(serializer)
#
Você pode chamar expect.addSnapshotSerializer
para adicionar um módulo que formata estruturas de dados específicas da aplicação.
Para um arquivo de teste individual, um módulo adicionado precede quaisquer módulos da configuração snapshotSerializers
, que precedem os serializadores de snapshot padrão para tipos internos de JavaScript e para elementos React. O último módulo adicionado é o primeiro módulo testado.
import serializer from 'my-serializer-module'; expect.addSnapshotSerializer(serializer); // affects expect(value).toMatchSnapshot() assertions in the test file
Se você adicionar um serializador de snapshot em arquivos de teste individual em vez de adicioná-lo à configuração snapshotSerializers
:
- Você torna a dependência explícita em vez de implícita.
- Você evita limites à configuração que podem fazer com que você tenha que ejetar create-react-app.
Consulte configurando Jest para obter maiores informações.
.not
#
Se você sabe como testar algo, .not
permite que você teste seu oposto. Por exemplo, este código testa que o melhor sabor da La Croix não é "coconut":
test('the best flavor is not coconut', () => { expect(bestLaCroixFlavor()).not.toBe('coconut'); });
.resolves
#
disponível no Jest 20.0.0+ #
Use resolves
para decodificar o valor de uma promessa cumprida, para que qualquer outro matcher possa então ser encadeado. Se a promessa for rejeitada a verificação falhará.
Por exemplo, este código de testes que a promessa resolve e que o valor resultante é 'lemon'
:
test('resolves to lemon', () => { // make sure to add a return statement return expect(Promise.resolve('lemon')).resolves.toBe('lemon'); });
Como alternativa, você pode usar async/await
em combinação com .resolves
:
test('resolves to lemon', async () => { await expect(Promise.resolve('lemon')).resolves.toBe('lemon'); await expect(Promise.resolve('lemon')).resolves.not.toBe('octopus'); });
.rejects
#
disponível no Jest 20.0.0+ #
Use .rejects
para decodificar o motivo de uma promessa rejeitada, para que qualquer outro matcher possa ser encadeado. Se a promessa é cumprida a verificação falhará.
Por exemplo, este código testa que a promessa rejeite com um motivo:
test('fetchData() rejects to be error', () => { // make sure to add a return statement return expect(Promise.reject('octopus')).rejects.toBeDefined(); });
Como alternativa, você pode usar async/await
em combinação com .rejects
. Além disso, esse código testa que o motivo retornado inclui 'octopus':
test('fetchData() rejects to be error', async () => { const drinkOctopus = new Promise(() => { throw new DisgustingFlavorError('yuck, octopus flavor'); }); await expect(drinkOctopus).rejects.toMatch('octopus'); });
.toBe(value)
#
toBe
só verifica que um valor é o que você espera. Ele usa ===
para verificar igualdade estrita.
Por exemplo, este código irá validar algumas propriedades do objeto can
:
const can = { name: 'pamplemousse', ounces: 12, }; describe('the can', () => { test('has 12 ounces', () => { expect(can.ounces).toBe(12); }); test('has a sophisticated name', () => { expect(can.name).toBe('pamplemousse'); }); });
Não use toBe
com números de ponto flutuante. Por exemplo, devido a arredondamentos, em JavaScript 0.2 + 0.1
não é estritamente igual a 0.3
. Se você tem números de ponto flutuante, tente usar de preferência .toBeCloseTo
.
.toHaveBeenCalled()
#
Também sob o pseudônimo: .toBeCalled()
Use .toHaveBeenCalled
para garantir que uma função de simulação (mock, em inglês) foi chamada.
Por exemplo, vamos dizer você tem uma função drinkAll(drink, flavor)
que usa uma função drink
e aplica a todas as bebidas disponíveis. Você pode querer verificar que drink
é chamada por 'lemon'
, mas não para 'octopus'
, porque o sabor 'octopus'
é realmente estranho e por que alguma coisa teria sabor de 'octopus' (polvo)? Você pode fazer isso com este conjunto de testes:
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)
#
Use .toHaveBeenCalledTimes
para garantir que uma função de simulação (mock, em inglês) foi chamada um número exato de vezes.
Por exemplo, vamos dizer você tem uma função drinkEach(drink, Array<flavor>)
que usa uma função drink
e aplica ela ao array das bebidas passadas. Você pode querer verificar que a função "drink" foi chamada um número exato de vezes. Você pode fazer isso com este conjunto de testes:
test('drinkEach drinks each drink', () => { const drink = jest.fn(); drinkEach(drink, ['lemon', 'octopus']); expect(drink).toHaveBeenCalledTimes(2); });
.toHaveBeenCalledWith(arg1, arg2, ...)
#
Também sob o pseudônimo: .toBeCalledWith()
Use .toHaveBeenCalledWith
para garantir que uma função de simulação (mock, em inglês) foi chamada com argumentos específicos.
Por exemplo, digamos que você pode registrar uma bebida com uma função register
, e applyToAll(f)
deve aplicar a função f
para todas as bebidas registradas. Para garantir que isso funciona, você poderia escrever:
test('registration applies correctly to orange La Croix', () => { const beverage = new LaCroix('orange'); register(beverage); const f = jest.fn(); applyToAll(f); expect(f).toHaveBeenCalledWith(beverage); });
.toHaveBeenLastCalledWith(arg1, arg2, ...)
#
Também sob o pseudônimo: .lastCalledWith(arg1, arg2, ...)
Se você tiver uma função de simulação (mock, em inglês), você pode usar .toHaveBeenLastCalledWith
para testar com quais argumentos foi chamada na última vez. Por exemplo, digamos que você tem uma função applyToAllFlavors(f)
que aplica f
para um monte de sabores, e você deseja garantir que quando você chamá-la, o último sabor em que ela opera é 'mango'
. Você pode escrever:
test('applying to all flavors does mango last', () => { const drink = jest.fn(); applyToAllFlavors(drink); expect(drink).toHaveBeenLastCalledWith('mango'); });
.toBeCloseTo(number, numDigits)
#
Usando a igualdade exata com números de ponto flutuante é uma má ideia. Arredondamento significa que coisas intuitivas falharão. Por exemplo, este teste vai falhar:
test('adding works sanely with simple decimals', () => { expect(0.2 + 0.1).toBe(0.3); // Fails! });
Ele falha porque em JavaScript, 0.2 + 0.1
na verdade é 0.30000000000000004
. Me desculpe.
Em vez disso, use .toBeCloseTo
. Use numDigits
para controlar quantos dígitos verificar após o ponto decimal. Por exemplo, se você quer ter certeza que 0.2 + 0.1
é igual a 0.3
, com uma precisão de 5 casas decimais, você pode usar este teste:
test('adding works sanely with simple decimals', () => { expect(0.2 + 0.1).toBeCloseTo(0.3, 5); });
O valor padrão para numDigits
é 2, que provou ser um bom padrão na maioria dos casos.
.toBeDefined()
#
Use .toBeDefined
para verificar que uma variável não "undefined". Por exemplo, se você quiser verificar que uma função fetchNewFlavorIdea()
retorna alguma cpisa, você pode escrever:
test('there is a new flavor idea', () => { expect(fetchNewFlavorIdea()).toBeDefined(); });
Você poderia escrever expect(fetchNewFlavorIdea()).not.toBe(undefined)
, mas é uma melhor prática evitar referência a undefined
diretamente em seu código.
.toBeFalsy()
#
Usar .toBeFalsy
quando você não se importa qual valor é, você só quer garantir que um valor é "false" em um contexto booleano. Por exemplo, digamos que você tem algum código de aplicativo que se parece com:
drinkSomeLaCroix(); if (!getErrors()) { drinkMoreLaCroix(); }
Você pode não se importar com o que getErrors
retorna, especificamente - ele pode retornar false
, null
ou ``, e seu código ainda funcionaria. Então se você quiser testar que não existem erros depois de beber algumas La Croix, você poderia escrever:
test('drinking La Croix does not lead to errors', () => { drinkSomeLaCroix(); expect(getErrors()).toBeFalsy(); });
Em JavaScript, existem seis valores "falsy" (que se traduzem em falso quando avaliados em um contexto booleano): false
, `,
'',
null,
undefinede
NaN`. Todo o resto é "truthy" (se traduzem em verdadeiro quando avaliados em um contexto booleano).
.toBeGreaterThan(number)
#
Para comparar números com ponto flutuante, você pode usar toBeGreaterThan
. Por exemplo, se você quiser testar que ouncesPerCan()
retorna um valor maior que 10 onças, escreva:
test('ounces per can is more than 10', () => { expect(ouncesPerCan()).toBeGreaterThan(10); });
.toBeGreaterThanOrEqual(number)
#
Para comparar números com ponto flutuante, você pode usar toBeGreaterThanOrEqual
. Por exemplo, se você quiser testar que ouncesPerCan()
retorna um valor de pelo menos 12 onças, escreva:
test('ounces per can is at least 12', () => { expect(ouncesPerCan()).toBeGreaterThanOrEqual(12); });
.toBeLessThan(number)
#
Para comparar números com ponto flutuante, você pode usar toBeLessThan
. Por exemplo, se você quiser testar que ouncesPerCan()
retorna um valor menor que 20 onças, escreva:
test('ounces per can is less than 20', () => { expect(ouncesPerCan()).toBeLessThan(20); });
.toBeLessThanOrEqual(number)
#
Para comparar números com ponto flutuante, você pode usar toBeLessThanOrEqual
. Por exemplo, se você quiser testar que ouncesPerCan()
retorna um valor de no máximo 12 onças, escreva:
test('ounces per can is at most 12', () => { expect(ouncesPerCan()).toBeLessThanOrEqual(12); });
.toBeInstanceOf(Class)
#
Use .toBeInstanceOf(Class)
para verificar que um objeto é uma instância de uma classe. Este "matcher" usa instanceof
por debaixo.
class A {} expect(new A()).toBeInstanceOf(A); expect(() => {}).toBeInstanceOf(Function); expect(new A()).toBeInstanceOf(Function); // throws
.toBeNull()
#
.toBeNull()
é o mesmo que .toBe(null)
, mas as mensagens de erro são um pouco mais agradáveis. Então use .toBeNull()
quando você deseja verificar que algo é nulo.
function bloop() { return null; } test('bloop returns null', () => { expect(bloop()).toBeNull(); });
.toBeTruthy()
#
Usar .toBeTruthy
quando você não se importa qual valor é, você só quer garantir que um valor é verdadeiro em um contexto booleano. Por exemplo, digamos que você tem algum código de aplicativo que se parece com:
drinkSomeLaCroix(); if (thirstInfo()) { drinkMoreLaCroix(); }
Você pode não se importar o que thirstInfo
retorna, especificamente - ele pode retornar true
ou um objeto complexo, e seu código ainda funcionaria. Então se você quiser apenas testar que thirstInfo
será "truthy" depois de beber algumas La Croix, você poderia escrever:
test('drinking La Croix leads to having thirst info', () => { drinkSomeLaCroix(); expect(thirstInfo()).toBeTruthy(); });
Em JavaScript, existem seis valores "falsy" (que se traduzem em falso quando avaliados em um contexto booleano): false
, `,
'',
null,
undefinede
NaN`. Todo o resto é "truthy" (se traduzem em verdadeiro quando avaliados em um contexto booleano).
.toBeUndefined()
#
Use .toBeUndefined
para verificar se uma variável é "undefined". Por exemplo, se você quiser verificar que uma função bestDrinkForFlavor(flavor)
retornará undefined
para o sabor 'octopus'
, porque não há nenhuma boa bebida com sabor "octopus", ou polvo:
test('the best drink for octopus flavor is undefined', () => { expect(bestDrinkForFlavor('octopus')).toBeUndefined(); });
Você poderia escrever expect(bestDrinkForFlavor('octopus')).toBe(undefined)
, mas é uma melhor prática evitar se referir a undefined
diretamente em seu código.
.toContain(item)
#
Use .toContain
quando você deseja verificar se um item está em uma lista. Para testar os itens na lista, ele usa ===
, uma verificação de igualdade estrita.
Por exemplo, se getAllFlavors()
retorna uma lista de sabores e você quer ter certeza que lime
está lá, você pode escrever:
test('the flavor list contains lime', () => { expect(getAllFlavors()).toContain('lime'); });
.toContainEqual(item)
#
Use .toContainEqual
quando você deseja verificar se um item está em uma lista. Para testar os itens na lista, este "matcher" recursivamente verifica a igualdade de todos os campos, em vez de verificar a identidade do objeto.
describe('my beverage', () => { test('is delicious and not sour', () => { const myBeverage = {delicious: true, sour: false}; expect(myBeverages()).toContainEqual(myBeverage); }); });
.toEqual(value)
#
Use .toEqual
quando você deseja verificar se dois objetos têm o mesmo valor. Este "matcher" recursivamente verifica a igualdade de todos os campos, em vez de verificar a identidade do objeto — isso é também conhecido como "igualdade profunda". Por exemplo, toEqual
e toBe
se comportam diferentemente neste conjunto de testes, para que todos os testes passem:
const can1 = { flavor: 'grapefruit', ounces: 12, }; const can2 = { flavor: 'grapefruit', ounces: 12, }; describe('the La Croix cans on my desk', () => { test('have all the same properties', () => { expect(can1).toEqual(can2); }); test('are not the exact same can', () => { expect(can1).not.toBe(can2); }); });
Nota:
.toEqual
não irá executar uma verificação de igualdade profunda para dois erros. Apenas a propriedademessage
de um Error é considerada pela igualdade. É recomendável usar o "matcher".toThrow
para testes contra erros.
.toHaveLength(number)
#
Use .toHaveLength
para verificar que um objeto tem uma propriedade .length
e está definida para um determinado valor numérico.
Isto é especialmente útil para verificar arrays ou tamanho de strings.
expect([1, 2, 3]).toHaveLength(3); expect('abc').toHaveLength(3); expect('').not.toHaveLength(5);
.toMatch(regexpOrString)
#
Use .toMatch
para verificar se uma string corresponde a uma expressão regular.
Por exemplo, você talvez não saiba o que exatamente essayOnTheBestFlavor()
retorna, mas você sabe que é uma string muito longa, e a substring grapefruit
deve estar em algum lugar. Você pode testar isso com:
describe('an essay on the best flavor', () => { test('mentions grapefruit', () => { expect(essayOnTheBestFlavor()).toMatch(/grapefruit/); expect(essayOnTheBestFlavor()).toMatch(new RegExp('grapefruit')); }); });
Este "matcher" também aceita uma string, a qual tentará corresponder:
describe('grapefruits are healthy', () => { test('grapefruits are a fruit', () => { expect('grapefruits').toMatch('fruit'); }); });
.toMatchObject(object)
#
Use .toMatchObject
para verificar se um objeto JavaScript corresponde a um subconjunto das propriedades de um objeto. Combinará objetos recebidos com propriedades que não estão no objeto esperado.
Você também pode passar uma array de objetos, neste caso o método retornará verdadeiro somente se cada objeto na matriz recebida corresponder (no sentido toMatchObject
descrito acima) o objeto correspondente no array esperado. Isso é útil se você deseja verificar que dois arrays correspondem em seu número de elementos, em oposição a arrayContaining
, que permite elementos extras no array recebido.
Você pode corresponder propriedades contra valores ou "matchers".
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); });
describe('toMatchObject applied to arrays arrays', () => { test('the number of elements must match exactly', () => { expect([ { foo: 'bar' }, { baz: 1 } ]).toMatchObject([ { foo: 'bar' }, { baz: 1 } ]); }); // .arrayContaining "matches a received array which contains elements that are *not* in the expected array" test('.toMatchObject does not allow extra elements', () => { expect([ { foo: 'bar' }, { baz: 1 } ]).toMatchObject([ { foo: 'bar' } ]); }); test('.toMatchObject is called for each elements, so extra object properties are okay', () => { expect([ { foo: 'bar' }, { baz: 1, extra: 'quux' } ]).toMatchObject([ { foo: 'bar' }, { baz: 1 } ]); }); });
.toHaveProperty(keyPath, value)
#
Use .toHaveProperty
para verificar se a propriedade fornecida na referência keyPath
existe para um objeto. Para verificação de propriedades aninhadas profundamente em um objeto use dot notation para referências profundas.
Opcionalmente, você pode fornecer um value
para verificar se é igual ao valor presente no keyPath
no objeto de destino. Este "matcher" usa 'igualdade profunda' (como toEqual()
) e recursivamente verifica a igualdade de todos os campos.
O exemplo a seguir contém um objeto houseForSale
com propriedades aninhadas. Estamos usando toHaveProperty
para verificar a existência e valores de várias propriedades no objeto.
// 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'); });
.toMatchSnapshot(optionalString)
#
Isso garante que um valor corresponda ao snapshot mais recente. Confira o guia de Teste de Snapshot para obter mais informações.
Você também pode especificar um nome opcional de snapshot. Caso contrário, o nome é inferido a partir do teste.
Nota: Embora teste de snapshot é mais comumente usado com componentes React, qualquer valor serializado pode ser usado como um snapshot.
.toThrow(error)
#
Também sob o pseudônimo: .toThrowError(error)
Use .toThrow
para testar que uma função é capaz de lançar erros quando é chamada. Por exemplo, se queremos testar que drinkFlavor('octopus')
lança um erro, porque o sabor "octopus", ou polvo, é muito nojento para beber, podemos escrever:
test('throws on octopus', () => { expect(() => { drinkFlavor('octopus'); }).toThrow(); });
Se você deseja testar que um erro específico é lançado, você pode fornecer um argumento para toThrow
. O argumento pode ser uma string para a mensagem de erro, uma classe para o erro, ou uma regex que deve coincidir com o erro. Por exemplo, digamos que drinkFlavor
é codificado como segue:
function drinkFlavor(flavor) { if (flavor == 'octopus') { throw new DisgustingFlavorError('yuck, octopus flavor'); } // Do some other stuff }
Podemos fazer um teste se esse erro é lançado de diversas maneiras:
test('throws on octopus', () => { function drinkOctopus() { drinkFlavor('octopus'); } // Test the exact error message expect(drinkOctopus).toThrowError('yuck, octopus flavor'); // Test that the error message says "yuck" somewhere expect(drinkOctopus).toThrowError(/yuck/); // Test that we get a DisgustingFlavorError expect(drinkOctopus).toThrowError(DisgustingFlavorError); });
.toThrowErrorMatchingSnapshot()
#
Use .toThrowErrorMatchingSnapshot
para testar que uma função lança um erro que corresponde ao snapshot mais recente quando é chamada. Por exemplo, digamos que você tem uma função drinkFlavor
que lança um erro sempre que o sabor é 'octopus'
, e é codificada como segue:
function drinkFlavor(flavor) { if (flavor == 'octopus') { throw new DisgustingFlavorError('yuck, octopus flavor'); } // Do some other stuff }
O teste para esta função ficará assim:
test('throws on octopus', () => { function drinkOctopus() { drinkFlavor('octopus'); } expect(drinkOctopus).toThrowErrorMatchingSnapshot(); });
E irá gerar o seguinte snapshot:
exports[`drinking flavors throws on octopus 1`] = `"yuck, octopus flavor"`;
Confira React Tree Snapshot Testing para obter mais informações sobre testes de snapshot.