E2E-тесты NestJS с supertest
↑ 6.4 Тестирование в NestJS · ← Предыдущая
Зачем это на собесе
Аналог
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 не завершится. - Тесты не должны зависеть от порядка выполнения.
- Не используйте «одну общую БД» без очистки.
Практика
- Напишите e2e для CRUD заказов с реальной БД в контейнере.
- Проверьте 401/403 для защищённых маршрутов.
- Выведите общий
setupApp(app)и используйте вmain.tsи тестах.
Вопросы с ответами
Чем e2e отличается от unit в Nest?
E2E проходит весь HTTP-конвейер (pipes, guards, фильтры) с реальными или подменёнными внешними зависимостями.
Почему тест не завершается?
Не закрыто приложение или соединения с БД.