npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@tresdoce-nestjs-toolkit/test-utils

v3.0.12

Published

Tresdoce NestJS Toolkit - Utilities para testing

Readme

Esta librería está pensada para ser utilizada en NestJS Starter o en este monorepo de funcionalidades, o cualquier proyecto que utilice una configuración centralizada, siguiendo la misma arquitectura del starter.

Al momento de realizar los tests, puede existir la necesidad de implementar una configuración para el ConfigModule, lo cual a veces se vuelve tedioso tener que estar creando un mock puntual para cada test, generando además duplicidad de código, como también la utilización de algún servicio que requiera el código, como puede ser una base de datos para tests, sin tener la infraestructura disponible para dichas pruebas.

Por esta razón, y con el fin de desarrollar los tests de manera más ágil y sin preocupaciones, surge la idea de esta librería que maneja de manera centralizada todo lo necesario para los tests.

Glosario


📝 Requerimientos básicos

🛠️ Instalar dependencia

npm install -D @tresdoce-nestjs-toolkit/test-utils
yarn add -D @tresdoce-nestjs-toolkit/test-utils

📦 Dependencias internas

Este paquete no tiene dependencias internas del toolkit. Puede utilizarse de forma independiente.

👨‍💻 Configuración base y dinámica

Configuración base para tests

La función config provee una configuración estándar del ConfigModule para los tests, basada en appConfigBase.

import { config } from '@tresdoce-nestjs-toolkit/test-utils';

describe('Suite for base config', () => {
  let app: INestApplication;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      imports: [
        ConfigModule.forRoot({
          isGlobal: true,
          load: [config],
        }),
        //...
      ],
    }).compile();

    app = module.createNestApplication();
    await app.init();
  });
  //...
});

Configuración dinámica para tests

La función dynamicConfig permite sobreescribir propiedades específicas de appConfigBase usando un merge profundo, sin reemplazar completamente la configuración base.

import { dynamicConfig } from '@tresdoce-nestjs-toolkit/test-utils';

describe('Suite for dynamic config', () => {
  let app: INestApplication;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      imports: [
        ConfigModule.forRoot({
          isGlobal: true,
          load: [
            dynamicConfig({
              httpOptions: {
                timeout: 5000,
                maxRedirects: 5,
              },
            }),
          ],
        }),
        //...
      ],
    }).compile();

    app = module.createNestApplication();
    await app.init();
  });
  //...
});

🎭 JestFN — mocks de Jest

El namespace JestFN contiene funciones de mock listas para usar en los tests. Se importa como namespace:

import { JestFN } from '@tresdoce-nestjs-toolkit/test-utils';

JestFN.config()

Retorna un mock de función que, al ser llamada, devuelve appConfigBase. Útil para mockear la función de configuración en tests unitarios.

import { JestFN } from '@tresdoce-nestjs-toolkit/test-utils';

jest.mock('@nestjs/config', () => ({
  ConfigService: jest.fn().mockImplementation(() => ({
    get: JestFN.config(),
  })),
}));

JestFN.executionContext()

Retorna un mock del ExecutionContext de NestJS con todos sus métodos (switchToHttp, getRequest, getResponse, getType, getClass, getHandler) mockeados con jest.fn().mockReturnThis().

import { JestFN } from '@tresdoce-nestjs-toolkit/test-utils';

describe('MyInterceptor', () => {
  it('should call next', () => {
    const context = JestFN.executionContext();
    // context.switchToHttp() está disponible como mock
  });
});

😝 CreateMock

createMock es una función que facilita la creación de mocks para peticiones HTTP utilizando Nock como base. cleanAllMock limpia todos los interceptores nock registrados.

import { createMock, cleanAllMock } from '@tresdoce-nestjs-toolkit/test-utils';

describe('MyController', () => {
  beforeEach(async () => {
    cleanAllMock();
  });

  it('should return user data from mock', async () => {
    createMock({
      url: 'https://test.com/api/user/1',
      method: 'get',
      statusCode: 200,
      responseBody: {
        id: 1,
        firstName: 'John',
        lastName: 'Doe',
        email: '[email protected]',
      },
    });
    const user = await controller.getUser();
    expect(user).toHaveProperty('firstName', 'John');
  });
});

Tipos de responseBody

JSON

createMock({
  url: 'http://example.com/api/data',
  method: 'get',
  statusCode: 200,
  responseBody: { success: true },
});

String

createMock({
  url: 'http://example.com/api/message',
  method: 'get',
  statusCode: 200,
  responseBody: 'Success message',
});

Buffer

createMock({
  url: 'http://example.com/api/file',
  method: 'get',
  statusCode: 200,
  responseBody: Buffer.from('Some binary data'),
});

Función (lazy evaluation)

createMock({
  url: 'http://example.com/api/dynamicData',
  method: 'get',
  statusCode: 200,
  responseBody: () =>
    JSON.parse(fs.readFileSync(path.resolve(__dirname, '../path/to/fixture.json'), 'utf8')),
});

Parámetros de createMock

| Parámetro | Tipo | Requerido | Descripción | | -------------- | ----------------------------------------------------------- | --------- | ----------------------------------------------------------------------- | | url | string | Sí | URL completa a interceptar | | method | HttpMethod | Sí | Método HTTP: get, post, put, head, patch, delete, options | | statusCode | number | Sí | Código de estado HTTP de la respuesta | | responseBody | string \| object \| unknown[] \| Buffer \| (() => object) | Sí | Cuerpo de la respuesta | | reqBody | string \| object \| Buffer | No | Cuerpo del request esperado (para métodos POST/PUT/PATCH) | | queryParams | QueryParams | No | Query params esperados en el request | | options | Options & { reqheaders? } | No | Opciones adicionales de nock (incluyendo headers esperados) |

🧪 TestContainers

TestContainers es una librería que utiliza Docker para instanciar servicios durante el entorno de testing, tanto local como en pipelines CI/CD.

Global Container (docker-compose)

Instancia uno o más servicios a partir de un docker-compose.yml. Ideal para tests de integración que necesitan múltiples servicios disponibles en toda la suite.

1. Configurar jest.config.ts:

//./jest.config.ts
import { jestConfig } from '@tresdoce-nestjs-toolkit/commons';
import * as dotenv from 'dotenv';

process.env.NODE_ENV = 'test';
dotenv.config({ path: '.env.test' });

module.exports = {
  ...jestConfig(),
  globalSetup: './jest.globalSetup.ts',
  globalTeardown: './jest.globalTeardown.ts',
};

2. Crear jest.globalSetup.ts:

//./jest.globalSetup.ts
import { initDockerCompose } from '@tresdoce-nestjs-toolkit/test-utils';

const services = ['mongo', 'redis', 'elasticsearch'];
module.exports = initDockerCompose(services);

Con opciones avanzadas:

import { initDockerCompose } from '@tresdoce-nestjs-toolkit/test-utils';
import * as path from 'path';

const services = ['mongo', 'redis'];
const composeFilePath = path.resolve(__dirname, 'fixtures', 'docker-compose');
const composeFile = 'docker-compose-test.yml';
const startupTimeout = 90000; // 90 segundos

module.exports = initDockerCompose(services, composeFilePath, composeFile, startupTimeout, {
  // Aplica Wait.forHealthCheck() a todos los containers
  useDefaultHealthCheckWaitStrategy: false,
  // Aplica Wait.forHealthCheck() solo a los containers listados (por nombre real del container)
  healthCheckWaitStrategyNames: ['my-service-1'],
});

3. Crear jest.globalTeardown.ts:

//./jest.globalTeardown.ts
import { closeDockerCompose } from '@tresdoce-nestjs-toolkit/test-utils';

module.exports = closeDockerCompose({ removeVolumes: false });

4. docker-compose.yml de ejemplo:

version: '3.9'

services:
  mongo:
    image: mongo:5.0
    container_name: local-mongo
    restart: always
    ports:
      - '27017:27017'
    environment:
      TZ: 'America/Argentina/Buenos_Aires'
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: 123456
      MONGO_INITDB_DATABASE: test_db

  redis:
    image: redis:6.2-alpine
    container_name: local-redis
    restart: always
    ports:
      - '6379:6379'
    command: ['redis-server', '--appendonly', 'yes', '--requirepass', '123456']

⚠️ En caso de fallas en los pipelines, revisar que el docker-compose.yml esté bien configurado y que el host del runner sea el mismo que usa Docker. Ej.: http://localhost:6379 o http://docker:6379.

Generic Container

Instancia un container único con una imagen de Docker. Ideal para proyectos que usan un solo servicio o para tests aislados.

import { TCPostgresOptions, testContainers } from '@tresdoce-nestjs-toolkit/test-utils';

jest.setTimeout(70000);

describe('TypeOrm - Postgres', () => {
  let app: INestApplication;
  let container: testContainers;

  beforeAll(async () => {
    container = await new testContainers('postgres:13', TCPostgresOptions);
    await container.start();
  });

  afterAll(async () => {
    await container.stop({ removeVolumes: true });
  });

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      //...
    }).compile();

    app = module.createNestApplication();
    await app.init();
  });

  afterEach(async () => {
    await app.close();
  });
});

Esquema: new testContainers('<img-docker>:<tag>', options?, isSingleton?)

Patrón Singleton de testContainers

Para compartir una sola instancia del container entre varios tests:

// En lugar de `new testContainers(...)`:
const container = testContainers.getInstance('postgres:13', TCPostgresOptions);
await container.start();

getInstance() retorna la instancia existente si ya fue creada, o crea una nueva con _isSingleton = true.

Troubleshooting

Para solucionar failed: port is already allocated, cambiar el puerto del host manteniendo el del container:

await new testContainers('mongo:5.0', {
  ...TCMongoOptions,
  ports: [{ container: 27017, host: 27013 }],
});

Para limpiar containers, imágenes y volumes:

docker system prune --volumes
docker system prune -a

📦 Fixtures

Configuración base (appConfigBase)

Objeto de configuración de la aplicación utilizado por config y dynamicConfig.

manifest

Objeto con los metadatos del manifest de la aplicación (nombre, versión, descripción, dependencias, etc.) basado en appConfigBase.

import { manifest } from '@tresdoce-nestjs-toolkit/test-utils';

// manifest.name, manifest.version, manifest.apiPrefix, etc.

Fixtures de respuesta

Objetos de datos de ejemplo para usar en tests:

import {
  fixtureUserResponse,
  fixtureUserArrayResponse,
  fixturePostResponse,
  fixturePostArrayResponse,
} from '@tresdoce-nestjs-toolkit/test-utils';

| Fixture | Descripción | | -------------------------- | ------------------------------------------------------- | | fixtureUserResponse | Un objeto usuario ({ id, name, lastname }) | | fixtureUserArrayResponse | Array de dos objetos usuario | | fixturePostResponse | Un objeto post ({ id, title, description, isActive }) | | fixturePostArrayResponse | Array de dos objetos post |

Fixtures de TestContainers

Opciones pre-configuradas para contenedores de test:

| Fixture | Imagen recomendada | Puerto interno | | ------------------------ | ----------------------- | -------------- | | TCRedisOptions | redis:6.2-alpine | 6379 | | TCMongoOptions | mongo:5.0 | 27017 | | TCPostgresOptions | postgres:13 | 5432 | | TCMySqlOptions | mysql:8 | 3306 | | TCElasticSearchOptions | elasticsearch:8 | 9200 | | TCDynamoDBOptions | amazon/dynamodb-local | 8000 |

Variables de entorno disponibles en los fixtures:

| Constante | Valor | | ---------------- | --------------------------- | | tcUsername | 'root' | | tcPassword | '123456' | | tcDatabaseName | 'test_db' | | tcName | 'tresdoce-test-container' |

📖 API Reference

config

RegisterAs de NestJS que provee la configuración base (appConfigBase) para ConfigModule.

dynamicConfig(args?: DeepPartial<AppConfig>)

Función que retorna un RegisterAs con la configuración base fusionada con los argumentos provistos.

JestFN (namespace)

| Export | Tipo | Descripción | | --------------------------- | ------------------------------ | ------------------------------------- | | JestFN.config() | () => jest.Mock | Mock que retorna appConfigBase | | JestFN.executionContext() | () => MockedExecutionContext | Mock del ExecutionContext de NestJS |

createMock(options: CreateMock): Interceptor

Crea un interceptor nock. Ver tabla de parámetros en la sección CreateMock.

cleanAllMock(): void

Limpia todos los interceptores nock activos (nock.cleanAll()).

testContainers

Clase para manejar containers Docker individuales.

| Miembro | Firma | Descripción | | ---------------------- | -------------------------------------- | --------------------------------------------------------------------- | | constructor | (image, options?, isSingleton?) | Crea un nuevo container | | getInstance (static) | (image?, options?) => testContainers | Retorna la instancia singleton o crea una nueva | | start() | () => Promise<void> | Inicia el container | | stop(options?) | (StopOptions?) => Promise<void> | Detiene el container | | getEnvs() | () => Env | Retorna las variables de entorno del container | | getContainer() | () => StartedTestContainer | Retorna la instancia del container iniciado | | getHost() | () => string | Retorna el host del container (puede no ser localhost) | | getName() | () => string | Retorna el nombre del container | | getMappedPort(port) | (number) => number | Retorna el puerto mapeado en el host para el puerto de container dado | | isStarted() | () => boolean | Indica si el container está iniciado |

ITestContainerOptions

| Campo | Tipo | Descripción | | --------------------- | --------------------------- | ----------------------------------------------------- | | ports | PortWithOptionalBinding[] | Puertos a exponer ([{ container, host }]) | | envs | Env | Variables de entorno del container | | networkName | string | Modo de red Docker | | containerName | string | Nombre del container | | startupTimeout | number | Timeout de inicio en milisegundos | | command | string[] | Comando a ejecutar en el container | | strategyHealthCheck | boolean | Usa Wait.forHealthCheck() como estrategia de inicio | | reuse | boolean | Reutiliza el container si ya está corriendo |

initDockerCompose(services?, composeFilePath?, composeFile?, startupTimeout?, options?)

| Parámetro | Tipo | Default | Descripción | | ------------------------------------------- | ---------- | ---------------------- | ------------------------------------- | | services | string[] | [] | Servicios a iniciar (vacío = todos) | | composeFilePath | string | '.' | Directorio del compose file | | composeFile | string | 'docker-compose.yml' | Nombre del archivo compose | | startupTimeout | number | 60000 | Timeout de inicio en ms | | options.useDefaultHealthCheckWaitStrategy | boolean | false | Aplica health check a todos | | options.healthCheckWaitStrategyNames | string[] | [] | Containers con health check selectivo |

closeDockerCompose(options?): () => Promise<void>

Retorna una función async compatible con globalTeardown de Jest que detiene el compose.

Utilidades

| Función | Firma | Descripción | | ---------- | ----------------------------------------------- | ------------------------------------ | | delay | (timeout?: number) => Promise<void> | Espera timeout ms (default: 10000) | | pathJoin | (dirName: string, fileName: string) => string | Une dos segmentos de path |

📄 Changelog

Todos los cambios notables de este paquete se documentarán en el archivo Changelog.