Skip to content

NestJS Unit Testing

Unit tests isolate a single provider. This lesson walks through TestingModule setup, mocking dependencies, and asserting service behavior with Jest.

Testing a Service in Isolation

Create a testing module that provides the service under test and value stubs for its dependencies. Compile the module, get the service, and assert method results and mock call arguments.

describe('CatsService', () => {
  let service: CatsService;
  const repo = { findAll: jest.fn(), findOne: jest.fn() };

  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({
      providers: [CatsService, { provide: CatsRepository, useValue: repo }],
    }).compile();
    service = moduleRef.get(CatsService);
    jest.clearAllMocks();
  });

  it('throws when missing', async () => {
    repo.findOne.mockResolvedValue(null);
    await expect(service.findOne(1)).rejects.toBeInstanceOf(NotFoundException);
  });
});

Clear mocks between tests so call counts and return values do not leak across cases.

Useful TestingModule APIs

moduleRef.get(CatsService)
moduleRef.resolve(RequestScopedService) // for REQUEST scope
overrideProvider(X).useValue(mock)
  • get() retrieves singleton providers; resolve() for transient/request scoped.
  • Override providers after importing a real module with .overrideProvider().
  • Prefer asserting thrown Nest exceptions for expected failure paths.
  • Keep tests readable with Arrange-Act-Assert structure.

Unit Testing Cheatsheet

Jest + Nest patterns.

Pattern Example
Mock function jest.fn() / mockResolvedValue
Spy jest.spyOn(obj, 'method')
Exception assert rejects.toBeInstanceOf(NotFoundException)
Call assert expect(repo.save).toHaveBeenCalledWith(...)

Partial Mocks

Only mock methods the test touches. Over-specified mocks become brittle when signatures evolve.

Controlling Time

Use Jest fake timers when testing expiration, retries, or scheduled logic.

Common Mistakes

  • Not awaiting async assertions.
  • Reusing the same mock object mutations across tests.
  • Testing private methods directly.
  • Importing the entire AppModule for a single service unit test.

Key Takeaways

  • TestingModule isolates providers with mocked dependencies.
  • Assert return values, thrown exceptions, and mock interactions.
  • Clear mocks between tests.
  • Override providers when building from real feature modules.

Pro Tip

When a unit test needs more than two or three mocks, reconsider whether the class under test has too many responsibilities.