Búsqueda de sitios web

node.js - ¿Cómo simular la implementación de la función createClient de redis en pruebas de integración con jest y supertest?


He creado una prueba unitaria para un repositorio de Redis que funciona bien:

import { RedisSecretRepository } from "../../../../src/adapters/repositories/RedisSecretRepository";
import { Secret } from "../../../../src/domain/models/Secret";
import { UrlId } from "../../../../src/domain/models/UrlId";
import { SecretNotFoundInRepositoryError } from "../../../../src/domain/models/errors/SecretNotFoundInRepository";

jest.mock("redis");
import { createClient } from "redis";
const mockedCreateClient = createClient as jest.MockedFunction<any>;

describe("Redis Secret Repository", () => {
    it("should get a secret by urlId", () => {
        const mockedRedisClient = {
            connect: jest.fn(),
            get: jest.fn(async () => "123qwe"),
            on: jest.fn(),
        };
        mockedCreateClient.mockReturnValue(mockedRedisClient);

        const redisSecretRepository = new RedisSecretRepository();

        expect(redisSecretRepository.getSecretByUrlId(new UrlId("123456qwerty")))
            .resolves.toEqual(new Secret("123qwe"));
        expect(mockedRedisClient.get).toBeCalledTimes(1);
        expect(mockedRedisClient.get).toBeCalledWith("123456qwerty");
    });
});

y aquí recibo mi mockedRedisClient y todo funciona bien, puedo simular mi comportamiento. Pero en la prueba de integración usando supertest, con la misma implementación y el mismo procedimiento de simulación, simplemente no funciona, no toma la implementación falsa:

import supertest from "supertest";
import server from "../../src/server";
const request = supertest(server.app);

jest.mock("redis");
import { createClient } from "redis";
const mockedCreateClient = createClient as jest.MockedFunction<any>;

describe("Get Secrets By Id Integration Tests", () => {
    it("should retrieve a secret", async () => {
        const mockedRedisClient = {
            connect: jest.fn(),
            get: jest.fn(async () => "123qwe"),
            on: jest.fn(),
        };
        mockedCreateClient.mockReturnValue(mockedRedisClient);

        const res = await request
            .get("/api/v1/secrets/123456qwerty");

        expect(createClient).toBeCalledTimes(3);
        console.log(res.body);
        expect(res.status).toBe(200);
        expect(res.body).toEqual({
            secret: "123qwe"
        });
    });
});

Usando esto, createClient está simulado, pero sin implementación. Está ignorando modificaciones posteriores como .mockReturnValue. En un enfoque diferente, podría codificar la implementación en la declaración del mock haciendo esto:

import { createClient } from "redis";
jest.mock("redis", () => {
    return {
        createClient: () => {
            return {
                connect: jest.fn(),
                get: jest.fn(async () => "123qwe"),
                on: jest.fn(),
            }
        }
    }
});

pero esto está codificado, no puedo cambiar la implementación para cada prueba donde quiero evaluar comportamientos diferentes. ¿Alguien sabe por qué pasa esto? ¿Supertest no me permite cambiar las implementaciones en tiempo de ejecución?

Artículos relacionados