DEV Community

Cover image for Writing Unit Tests for NestJS Modules with TypeORM Dependencies
Basa Saiteja
Basa Saiteja

Posted on

Writing Unit Tests for NestJS Modules with TypeORM Dependencies

When working with NestJS modules that rely on TypeORM, it’s common to encounter challenges in testing without invoking the actual database. Instead of using a real database, we can mock the TypeORM repository to ensure isolated and faster unit tests. Let’s walk through how to achieve this using an ExampleModule as our case study.

The ExampleModule Implementation

Here’s the implementation of a basic ExampleModule that has TypeORM dependencies:

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ExampleEntity } from './entities/example.entity';
import { ExampleService } from './example.service';
import { ExampleController } from './example.controller';

@Module({
  imports: [TypeOrmModule.forFeature([ExampleEntity])],
  controllers: [ExampleController],
  providers: [ExampleService],
})
export class ExampleModule {}
Enter fullscreen mode Exit fullscreen mode

Key Points:

  • The ExampleModule imports the TypeOrmModule and registers the ExampleEntity.

  • It defines a service (ExampleService) and a controller (ExampleController).

Why Mock TypeORM?

Directly connecting to a database during unit tests introduces dependencies that can:

  • Slow down test execution.

  • Cause flaky tests if the database state changes.

  • Make tests less predictable.

By mocking the TypeORM repository, we can:

  • Focus on testing the business logic.

  • Avoid any dependency on the database.

  • Achieve faster and more reliable tests.

Creating a Mock Module

We’ll create a mock module, MockExampleModule, which excludes TypeORM imports to bypass database interactions.

import { Module } from '@nestjs/common';
import { ExampleService } from './example.service';
import { ExampleController } from './example.controller';

@Module({
  imports: [],
  controllers: [ExampleController],
  providers: [ExampleService],
})
export class MockExampleModule {}
Enter fullscreen mode Exit fullscreen mode

Key Points:

  • The MockExampleModule excludes TypeOrmModule.

  • It retains the controller and service for testing.

Writing Test Cases

Here’s how you can write unit tests for ExampleModule:

example.module.spec.ts:

import { Test, TestingModule } from '@nestjs/testing';
import { getRepositoryToken } from '@nestjs/typeorm';
import { ExampleEntity } from './entities/example.entity';
import { ExampleService } from './example.service';
import { ExampleController } from './example.controller';
import { CustomLogger } from '../utilities';


describe('ExampleModule', () => {
  let service: ExampleService;

  // Mock repository methods
  const mockRepository = {
    find: jest.fn(),
    findOne: jest.fn(),
    save: jest.fn(),
    delete: jest.fn(),
  };

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      controllers: [ExampleController],
      providers: [
        ExampleService,
        {
          provide: getRepositoryToken(ExampleEntity), // Mock TypeORM repository
          useValue: mockRepository,
        },
        CustomLogger,      
      ],
    })
     .overrideModule(ExampleModule)
     .useModule(MockExampleModule) // override Module with a Mock
     .compile()

    service = module.get<ExampleService>(ExampleService);
  });

  it('should be defined', () => {
    expect(module).toBeDefined();
  });
});
Enter fullscreen mode Exit fullscreen mode

Key Points:

  • Mock Repository: Use jest.fn() to mock repository methods like find, findOne, save, and delete.

  • Override Module: Use overrideModule to replace the actual module with a mock.

  • MockExampleModule: Include the mock module to replace the original module’s imports and avoid TypeORM dependencies.

  • CustomLogger: Include your logger if necessary to ensure completeness

Conclusion

By following this approach, you can test your NestJS modules with TypeORM dependencies effectively without invoking the database. Mocking repositories ensures your tests are fast, reliable, and focused on the business logic. Start implementing this strategy in your projects to achieve robust and maintainable unit tests.

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read full post →

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay