DEV Community 👩‍💻👨‍💻

Cover image for Testes unitários Frontend - Como Mockar Módulos e React Hooks usando apenas o Jest
Fernanda Kipper
Fernanda Kipper

Posted on • Updated on

Testes unitários Frontend - Como Mockar Módulos e React Hooks usando apenas o Jest

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 useHistorydo módulo react-router. Nós podemos mockar a função pushe 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
  }
Enter fullscreen mode Exit fullscreen mode
  • 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
  })
}))
Enter fullscreen mode Exit fullscreen mode

🎯 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.

Caso queira saber mais sobre o objeto Jest e seus métodos, recomendo muito que você leia a documentação do Jest

  • 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'))
Enter fullscreen mode Exit fullscreen mode

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.

  1. 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'
Enter fullscreen mode Exit fullscreen mode
  • 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 ao jest.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')
Enter fullscreen mode Exit fullscreen mode

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
  })
Enter fullscreen mode Exit fullscreen mode

2.2 Caso contrário, guardaremos o retorno do spyOn em uma constante

  const useNomeDoMeuHookMock = jest.spyOn(MeuHook, 'useNomeDoMeuHook')
Enter fullscreen mode Exit fullscreen mode

E dentro de cada test case realizaremos a diferente implementação

test('It should ....', async () => {
  useNomeDoMeuHookMock.mockReturnValue(// valor retornado pelo hook)
})

Enter fullscreen mode Exit fullscreen mode

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()....
})
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
sleeperu_u profile image
Rene Sena

Muito bom, massa! Obrigado por compartilhar!!

Layoffs: It’s Okay to Not Be Okay