E2E-тесты NestJS с supertest

↑ 6.4 Тестирование в NestJS · ← Предыдущая

По желанию~3 мин чтенияУровень: junior

Зачем это на собесе

Аналог WebApplicationFactory в Node.js: проверка всего HTTP-конвейера.

Объяснение

E2E-тест поднимает приложение (без сетевого порта) и отправляет HTTP-запросы через supertest.

describe("Orders (e2e)", () => {
  let app: INestApplication;
 
  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({ imports: [AppModule] })
      .overrideProvider(PaymentsGateway).useValue({ charge: jest.fn().mockResolvedValue({ ok: true }) })
      .compile();
    app = moduleRef.createNestApplication();
    app.useGlobalPipes(new ValidationPipe({ whitelist: true, transform: true }));  // как в main.ts
    await app.init();
  });
  afterAll(() => app.close());
 
  it("POST /orders создаёт заказ", async () => {
    const res = await request(app.getHttpServer())
      .post("/orders").set("Authorization", `Bearer ${token}`)
      .send({ customer: "A", quantity: 2 }).expect(201);
    expect(res.body).toMatchObject({ customer: "A" });
  });
 
  it("возвращает 400 при неверных данных", () =>
    request(app.getHttpServer()).post("/orders").send({ quantity: -1 }).expect(400));
});

Реальная БД: Testcontainers (@testcontainers/postgresql) + миграции; очистка данных между тестами (TRUNCATE в beforeEach). Внешние сервисы — nock/MSW/WireMock.

Нюансы и подводные камни

  • Настройки из main.ts (pipes, filters, prefix) нужно повторить в тесте, иначе тест проверяет другое приложение.
  • Не забывайте закрывать приложение и соединения (app.close()), иначе Jest не завершится.
  • Тесты не должны зависеть от порядка выполнения.
  • Не используйте «одну общую БД» без очистки.

Практика

  1. Напишите e2e для CRUD заказов с реальной БД в контейнере.
  2. Проверьте 401/403 для защищённых маршрутов.
  3. Выведите общий setupApp(app) и используйте в main.ts и тестах.

Вопросы с ответами

Связанные темы