Olá Pessoal! Nesse post eu vou explicar algumas maneiras que você pode adotar para realizar os mocks dos seus testes unitários.
Mockando imports de módulos
Caso as funções ou componentes que você deseja mockar nos seus testes venham de um módulo externo, existe uma maneira de utilizar apenas o objeto Jest para realizar o mock.
Exemplo, digamos que queremos testar se nosso componente está chamando corretamente a função push
retornada pelo hook useHistory
do módulo react-router
. Nós podemos mockar a função push
e usá-la no expect
do nosso teste para ter certeza que ela foi chamada, para fazer isso nos devemos:
- Criar uma função de mock usando o método do Jest
jest.fn()
que retorna uma função de simulação OU criar nossa própria implementação
// OPÇÃO 1
const mockPush = jest.fn()
// OPÇÃO 2
const mockPush = () => {
// alguma funcionalidade...
// return algo
}
- Mockar o import do módulo
react-router
no ínicio do arquivo antes de iniciar os testes, dessa forma toda vez que um componente renderizado pelo Jest durante o teste tentar importar esse módulo, o Jest substituirá o real conteúdo por aquele que nos mockamos
jest.mock('react-router', () => ({
...jest.requireActual('react-router'),
useHistory: () => ({
push: mockPush
})
}))
🎯 Note que usamos o método requireActual
do objeto Jest que retorna o módulo real e com o spread operator copiamos tudo do módulo verdadeiro e apenas subsstituimos o que precisávamos testar, nesse caso o hook useHistory
e seu retorno.
- Agora, ao escrever seu teste unitário você deve utilizar a função mockada
mockPush
para conferir o resultado com o expect, e pronto!
await waitFor(() => expect(mockPush).toHaveBeenCalledWith('sua-rota'))
Mockando React Hooks
Em testes unitários de componentes React, é muito comum precisarmos mockar Hooks para realizar verificações de comportamento em nossos componentes. Caso você deseja mockar apenas a implementação de um hook, também é possível utilizar apenas o objeto Jest para realizar nosso teste.
- Primeiro você deve importar todo o arquivo que contém seu hook, o que retornará um objeto que contém todos os retornos desse arquivo
import * as MeuHook from 'path-para-seu-hook'
-
No ínicio do arquivo antes de iniciar os testes mockaremos UM dos retornos desse arquivo, nesse caso o hook, usando o método do Jest
jest.spyOn
que cria uma função de mock similar aojest.fn
mas também observa todas as chamadas pelo objectDoArquivo[nomeDoMétodo]- O primeiro parâmetro que passamos ao jest.spyOn é justamente o objeto contendo todos os retornos do nosso arquivo
- E o segundo parâmetro é o nome do método (o nome do hook ou função) que é exportado desse arquivo e queremos observar (note, caso seu hook seja exportado através de um
export default
em vez de fornecermos o seu nome, passaremos 'default' como parâmetro)
jest.spyOn(MeuHook, 'useNomeDoMeuHook')
Agora temos duas opções, podemos mockar a implementação do hook para todo o nosso arquivo de teste, ou seja, para cada test case ele retornará o mesmo valor, OU, podemos realizar uma implementação diferente para cada test case
2.1 Caso queiramos a mesma implementação para todo o arquivo, podemos realizar a declaração junto com método spyOn
e todos os nossos tests cases terão acesso ao mesmo mock
jest.spyOn(MeuHook, 'useNomeDoMeuHook').mockImplementation(() =>
{
// implemente aqui
})
2.2 Caso contrário, guardaremos o retorno do spyOn em uma constante
const useNomeDoMeuHookMock = jest.spyOn(MeuHook, 'useNomeDoMeuHook')
E dentro de cada test case realizaremos a diferente implementação
test('It should ....', async () => {
useNomeDoMeuHookMock.mockReturnValue(// valor retornado pelo hook)
})
E por fim, não podemos nos esquecer de depois de cada teste limpar o mock para não sujar as implementações dos próximos testes, por isso colocaremos no inicio do nosso suite de testes a função afterEach
para resetar nosso mock
describe('...', () => {
afterEach(() => {
useNomeDoMeuHookMock.mockClear()
})
test()....
})
Obrigada por ter lido até aqui e espero que eu tenha te ajudado! Qualquer dúvida ou sugestão fique a vontade para entrar em contato comigo 😀
Top comments (1)
Muito bom, massa! Obrigado por compartilhar!!