CodePark/ questions / Testing Nest apps
START PRACTICINGPRACTICE
Backend question · NestJS › Testing Nest apps

How do you unit test a service that depends on a TypeORM repository, without a database?

const repo = { findOneBy: jest.fn(), save: jest.fn() };

beforeEach(async () => {
  const moduleRef = await Test.createTestingModule({
    providers: [
      UsersService,
      { provide: getRepositoryToken(User), useValue: repo },
    ],
  }).compile();
  service = moduleRef.get(UsersService);
});
it("finds a user", async () => {
  repo.findOneBy.mockResolvedValue({ id: 1 });
  expect(await service.findOne(1)).toEqual({ id: 1 });
});

Build a test module with Test.createTestingModule() and replace the repository with a mock under getRepositoryToken(User).

Test.createTestingModule() builds a small Nest module just for the test. You list the real service, and you replace its dependencies with fakes.

For TypeORM, getRepositoryToken(User) returns the same token that @InjectRepository(User) uses. A token is the key Nest uses to find a provider. So you provide a useValue object of jest.fn() methods under that token. This puts a mock repository in place of the real one.

Then:

  • compile() resolves all the dependencies.
  • moduleRef.get(UsersService) returns the service with the mock injected.
  • Each test sets return values, like mockResolvedValue.
  • Each test checks the result and how the repository was called.

For request-scoped or transient providers, use moduleRef.resolve() instead of get().

  • Build the test module with Test.createTestingModule({ providers }).
  • Provide a useValue mock under getRepositoryToken(Entity).
  • Call compile(), then get() the service.
  • Check both the results and the calls to the mock.
  • Use resolve() instead of get() for scoped providers.