Jest и TestingModule: unit-тесты провайдеров
↑ 6.4 Тестирование в NestJS · → Следующая
Зачем это на собесе
Как в Nest подменяют зависимости в тестах — аналог DI-подмены в .NET.
Объяснение
Test.createTestingModule собирает облегчённый модуль с нужными провайдерами и позволяет заменить зависимости.
describe("OrdersService", () => {
let service: OrdersService;
const repo = { findById: jest.fn(), save: jest.fn() };
beforeEach(async () => {
const moduleRef = await Test.createTestingModule({
providers: [OrdersService, { provide: OrdersRepository, useValue: repo }],
}).compile();
service = moduleRef.get(OrdersService);
jest.resetAllMocks();
});
it("бросает NotFound для неизвестного заказа", async () => {
repo.findById.mockResolvedValue(null);
await expect(service.find("42")).rejects.toBeInstanceOf(NotFoundException);
});
it("сохраняет заказ", async () => {
repo.save.mockResolvedValue({ id: "1" });
await service.create({ customer: "A", quantity: 1 });
expect(repo.save).toHaveBeenCalledWith(expect.objectContaining({ customer: "A" }));
});
});Полезные приёмы:
overrideProvider(X).useValue(mock),useMockerдля автоматических моков.jest.useFakeTimers()для времени;jest.spyOnдля частичных подмен.- Табличные тесты:
it.each([...]). - Vitest — быстрая альтернатива Jest с совместимым API.
Нюансы и подводные камни
- Тестируйте поведение, а не вызовы моков.
- Не забывайте
awaitпередexpect(...).rejects. - Общие моки между тестами без сброса дают зависимые тесты.
- Проверяйте типы: моки
useValueне проверяются компилятором на соответствие интерфейсу.
Практика
- Напишите unit-тесты сервиса заказов с заменой репозитория.
- Используйте
it.eachдля набора граничных случаев. - Протестируйте код со временем через fake timers.
Вопросы с ответами
Как подменить зависимость в Nest-тесте?
Указать альтернативный провайдер в
createTestingModuleилиoverrideProvider.
Jest или Vitest?
Совместимый API; Vitest быстрее и лучше работает с ESM/TypeScript.