Saltar a contenido

Mocking con Jest en aplicaciones frontend

En ocasiones es normal que usemos librerías, componentes, que al ser utilidades externas no tiene sentido que testeemos, y por lo tanto "mockear" o burlar comportamientos esperados.

Uno de los ejemplos más básicos es la librerías que actualmente tenemos en nuestros desarrollos son react-router-dom architecture-it/azure-b2c azure/msal-react swiper las cuales no nos interesa testear internamente su funcionamiento, si no esperar un resultado específico

Para ello tenemos varias maneras de mockear:

Si necesitamos constantemente mockear está librería en n archivos lo ideal es ir a un tipo de mock general, ¿Cómo se hace esto? Debemos generar un archivo en la carpeta __mocks__ que respete la estructura, de cómo se define el módulo, por ejemplo:

@architecture-it/azure-b2c
src/__mocks__/@architecture-it/azure-b2c.tsx
export const useUser = jest.fn();
export const addResponseInterceptorRefreshToken = jest.fn();
@azure/msal-react
src/__mocks__/@azure/msal-react.tsx
import { InteractionStatus } from "@azure/msal-browser";

export const useIsAuthenticated = jest.fn().mockImplementation(() => false);
export const useMsal = jest.fn().mockImplementation(() => ({ inProgress: InteractionStatus.None }));

export const MsalProvider = ({ children }: { children: React.ReactNode }) => <>{children}</>;
@elastic/apm-rum
src/__mocks__/@elastic/apm-rum.ts
export const init = jest.fn();

Y para finalizar la configuración sencillamente en el test tendríamos que hacer un jest.mock("@architecture-it/azure-b2c") al inicio del archivo.

En cambio mockear en línea, para casos puntuales que es posiblemente la que más se pueden leer en foros y en comunidades que es básicamente haciendo el mock en el archivo donde se necesite cómo por ejemplo:

jest.mock("@architecture-it/azure-b2c", () => ({
    useUser: jest.fn(),
    addResponseInterceptorRefreshToken: jest.fn(),
}));

Assets (estilos o imagenes)

En este caso se requiere dos niveles de configuración (ya viene por defecto en el template y la librería @architecture-it/rsbuild):

jest.config.js
const { generateJestConfig } = require("@architecture-it/rsbuild");

module.exports = generateJestConfig({
  moduleNameMapper: {
    // es para decirle a jest quie no busque resolverlo
    "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$":
      "__mocks__/fileMock.ts",
    "\\.(css|less|scss|sass)$": "identity-obj-proxy",
    "@/(.*)$": "<rootDir>/src/$1",
  },
});

Y el archivo fileMock.ts:

src/__mocks__/fileMock.ts
module.exports = "";