21 de maio de 20242 min de leitura

Como fazer mock de uma classe iniciada dentro do construtor

Neste post vou mostrar como fazer o mock de uma classe que é iniciada dentro do construtor usando o Jest.

Descrevendo o problema

Sabe quando temos uma classe e no método construtor da classe iniciamos outra classe?
Essa nova classe é uma dependência e há várias maneiras de lidarmos com isso.
A forma mais simples é no método construtor, nós iniciamos a classe e atribuímos para uma propriedade da classe, como o exemplo abaixo, onde EmailService é iniciada e atribuída para a propriedade emailService da classe ResetPasswordUseCase.

// emailService.js
class EmailService {

    sendEmail() {
        console.log('Sent..')
    }
}

// resetPasswordUseCase.js
import EmailService from './emailService.js'

class ResetPasswordUseCase {
   
    constructor() {
        this.emailService = new EmailService()
    }


    execute(email) {

        // Regras de necógio
        // Envio do email
        this.emailService.sendEmail(email)
    }
}

Neste exemplo, o caso de uso ResetPasswordUseCase tem como dependência a classe EmailService, que seria responsável pelo envio do email.
Essa situação é muito comum quando não usamos injeção de dependência.

O problema está ao testarmos o caso de uso, um dos casos de teste é verificar se o this.emailService.sendEmail() foi chamado corretamente.
E como vamos fazer o mock dessa função? Dado que ela se inicia dentro do construtor do caso de uso.

Como resolvi esse problema

Usando o Jest podemos fazer o mock no momento em que o import acontece e dessa forma ele vai usar a classe modificada ao invés da original.
Veja, no exemplo abaixo, como ficaria essa solução.

jest.mock('./emailService', () => {
    return {
      ...(jest.requireActual('./emailService')),
      EmailService: jest.fn().mockImplementation(() => ({
        sendEmail: () => jest.fn().mockResolvedValue(null),
      })),
    }
  })

Dessa forma a gente intercepta o import e o Jest vai usar o código que colocamos dentro do jest.mock para iniciar a classe EmailService e o método sendEmail é um mock do Jest que podemos verificar quantas vezes foi chamado e com quais argumentos.