2
respostas

[Dúvida] Utilidade de Mockar um função inteira

Estou começando a aprender agora sobre testes e não entendi quando o professor mocka uma função inteira e testa ela.

Qual o sentido de eu testar uma função que eu estou sobescrevendo? Isso não faria o teste passar sempre?

O código em questão é este:

  it('Deve fazer uma chamada simulada ao BD', () => {
    const editora = new Editora(objetoEditora);

    editora.salvar = jest.fn().mockReturnValue({
      id: 10,
      nome: 'CDC',
      cidade: 'Sao Paulo',
      email: 'c@c.com',
      created_at: '2022-10-01',
      updated_at: '2022-10-01',
    });

    const retorno = editora.salvar();

    expect(retorno).toEqual(
      expect.objectContaining({
        id: expect.any(Number),
        ...objetoEditora,
        created_at: expect.any(String),
        updated_at: expect.any(String),
      }),
    );
  });
});
2 respostas

Oi, Vinícius! Tudo bem?

A prática de "mockar" funções é muito útil em testes unitários e de integração, pois tem como objetivo isolar o comportamento da função para que possamos testar apenas o que é relevante para o nosso teste. No caso do nosso código, por exemplo, estamos "mockando" a função salvar da classe Editora, pois queremos testar se ela é chamada corretamente e se retorna o valor esperado.

Dessa forma, no nosso caso, o importante é notar que não estamos testando a implementação da função salvar, mas sim o seu comportamento, já que queremos garantir que, quando chamada, ela retorne um objeto com a estrutura esperada.

Por exemplo, imaginando que a função salvar faça uma chamada ao banco de dados, em um teste, não queremos que essa chamada seja realmente feita (pois isso tornaria o teste mais lento e poderia alterar o estado do nosso banco de dados de teste), então, ao invés disso, "mockamos" a função para que ela retorne um valor fixo.

Devido a isso, o teste não passará sempre, apenas se a função salvar for chamada e retornar um objeto com a estrutura esperada. Se a função for alterada para retornar algo diferente, o teste falhará, o que é exatamente o que queremos: um aviso de que algo mudou e que precisamos atualizar nossos testes ou nosso código.

Deixo como complemento um pequeno artigo sobre a temática para incrementar os estudos:

Espero ter ajudado! Caso tenha ficado alguma dúvida, sinta-se à vontade em comunicar, estou à disposição!

Um forte abraço e bons estudos!

Caso este post tenha te ajudado, por favor, marcar como solucionado ✓

Olá Sarah!

Obrigado pela resposta, seu esclarecimento me deu uma ideia que consegui testar.

Ao ver a implementação da função salvar() no objeto da biblioteca, temos o seguinte código:


  async salvar() {
    // verificar se o id existe no banco
    // se não existir é create
    // se existir é update
    if (this.id) {
      return this.atualizar(this.id);
    }
    return this.criar();
  }

O que fiz foi alterar o comportamento da função como você disse para que retornasse algo diferente, como null por exemplo:

  async salvar() {
    // verificar se o id existe no banco
    // se não existir é create
    // se existir é update
    // if (this.id) {
    //   return this.atualizar(this.id);
    // }
    // return this.criar();
    return null;
  }

Ao realizar essa modificação e rodar os testes, como esperado, o teste passou, o que não deveria acontecer já que a função está retornando null conforme o print abaixo:

Teste-exemplo-1

Pelo que entendi, a função que deveriamos mockar seria a criar(), que efetivamente faz a conexão com o banco de dados.

Ao alterar o código do teste para realizar o mock da função criar() o teste não passa, que a meu ver seria o comportamento correto.

Teste-Exemplo-2Esse entendimento faz sentido?

Fiz um pull request no repositório do curso com todas as alterações no código que realizei.

Pull Request