Skip to content

Instantly share code, notes, and snippets.

@joaovictorino
Last active January 19, 2024 02:58
Show Gist options
  • Save joaovictorino/61ad34bc4c5cc8d1048394381bb3757d to your computer and use it in GitHub Desktop.
Save joaovictorino/61ad34bc4c5cc8d1048394381bb3757d to your computer and use it in GitHub Desktop.
Trabalhando com mocks

Trabalhando com mocks

Vamos usar mocks agora para ter o mesmo comportamento que um acesso ao banco de dados, portanto crie o arquivo "TransferenciaServicoMock.test.ts" na mesma pasta de "TransferenciaServico.test.ts", com o conteúdo abaixo

import { TransferenciaServico } from "../../src/application/TransferenciaServico";
import { TransferenciaDTO } from "../../src/application/dto/TransferenciaDTO";
import { Conta } from "../../src/model/Conta";
import { Repositorio } from "../../src/model/contract/Repositorio";

describe("Transferencia serviço mock", () => {

    test("transferir com sucesso", async () => {
        const { repositorio, contaOrigem, contaDestino } = criarMock();

        const transferenciaServico: TransferenciaServico = new TransferenciaServico(repositorio);
        const dto: TransferenciaDTO = new TransferenciaDTO("123456", "654321", 100.0);
        const recibo: string = await transferenciaServico.transferir(dto);

        expect(repositorio.buscar).toBeCalledWith("123456");
        expect(repositorio.buscar).toBeCalledWith("654321");
        expect(repositorio.buscar).toBeCalledTimes(2);
        expect(repositorio.adicionar).toBeCalledWith(contaOrigem);
        expect(repositorio.adicionar).toBeCalledWith(contaDestino);
        expect(repositorio.adicionar).toBeCalledTimes(2);
        
        const contaOrigemRepo = await repositorio.buscar("123456");
        const contaDestinoRepo = await repositorio.buscar("654321");
        expect(contaOrigemRepo!.saldo).toBe(4900.0);
        expect(contaDestinoRepo!.saldo).toBe(5100.0);
        expect(recibo.length).toBe(6);
    });
});

function criarMock() {
    const dicionario: Map<string, Conta> = new Map<string, Conta>();
    const contaOrigem: Conta = new Conta("123456", 5000);
    const contaDestino: Conta = new Conta("654321", 5000);
    dicionario.set(contaOrigem.numero, contaOrigem);
    dicionario.set(contaDestino.numero, contaDestino);

    const repositorio: jest.Mocked<Repositorio<string, Conta>> = {
        adicionar: jest.fn((entidade: Conta) => {
            dicionario.set(entidade.numero, entidade);
        }),
        buscar: jest.fn((numero: string) => {
            const promise = new Promise<Conta | undefined>((resolve, reject) => {
                resolve(dicionario.get(numero));
            });
            return promise;
        })
    };

    return { repositorio, contaOrigem, contaDestino };
}

Agora rode os testes

npx jest

Perceba que o mock tem o mesmo comportamento do fake que criamos, mas sem a necessidade de criar outras classes e ainda com a possibilidade de validar as chamadas aos métodos.
Agora adicione no teste mais dois testes de fluxos alternativos, conforme abaixo

test("conta de origem não encontrada", async () => {
    const { repositorio } = criarMock();

    const transferenciaServico: TransferenciaServico = new TransferenciaServico(repositorio);
    const dto: TransferenciaDTO = new TransferenciaDTO("111111", "654321", 100.0);

    await expect(transferenciaServico.transferir(dto)).rejects.toEqual(Error("conta de origem não encontrada"));
    expect(repositorio.buscar).toBeCalledWith("111111");
    expect(repositorio.buscar).toBeCalledWith("654321");
    expect(repositorio.buscar).toBeCalledTimes(2);
    expect(repositorio.adicionar).not.toBeCalled();
});

test("conta de destino não encontrada", async () => {
    const { repositorio } = criarMock();

    const transferenciaServico: TransferenciaServico = new TransferenciaServico(repositorio);
    const dto: TransferenciaDTO = new TransferenciaDTO("123456", "222222", 100.0);

    await expect(transferenciaServico.transferir(dto)).rejects.toEqual(Error("conta de destino não encontrada"));
    expect(repositorio.buscar).toBeCalledWith("123456");
    expect(repositorio.buscar).toBeCalledWith("222222");
    expect(repositorio.buscar).toBeCalledTimes(2);
    expect(repositorio.adicionar).not.toBeCalled();
});

Novamente rode os testes

npx jest

Tudo funcionando conforme o esperado. Lembre-se que não são necessários dois conjuntos de testes de integração para a camada de aplicação, estamos fazendo isso apenas para exercitar possibilidades de dublês de testes, como fakes, spies e mocks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment