In NestJS/TypeORM applications, testing custom repositories typically involves unit testing and integration testing. The following outlines specific steps for testing custom repositories:
1. Unit Testing
Unit testing focuses on verifying individual repository functionalities without real database connections. We can use Jest and mocking to achieve this.
Steps:
-
Set up and configure Jest:
- Ensure Jest is installed in your NestJS project.
- Configure the
jest.config.jsfile to support TypeScript and NestJS structure.
-
Mock TypeORM functionalities:
- Use Jest's
mock()function to simulate Repository and other key TypeORM functionalities. - Create a mock repository using fake data and functions to replace real database operations.
- Use Jest's
-
Write test cases:
- Write test cases to verify each method of the repository.
- Use
expect()to validate function return values against expectations. - Ensure testing of boundary conditions and exception handling.
Example code:
typescriptimport { Test, TestingModule } from '@nestjs/testing'; import { getRepositoryToken } from '@nestjs/typeorm'; import { MyEntity } from './entities/my-entity.entity'; import { MyRepository } from './my.repository'; describe('MyRepository', () => { let repository: MyRepository; let mockRepository = { find: jest.fn(), findOne: jest.fn(), save: jest.fn(), delete: jest.fn() }; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ providers: [ MyRepository, { provide: getRepositoryToken(MyEntity), useValue: mockRepository, }, ], }).compile(); repository = module.get<MyRepository>(MyRepository); }); afterEach(() => { jest.clearAllMocks(); }); it('should find all entities', async () => { mockRepository.find.mockResolvedValue(['entity1', 'entity2']); expect(await repository.findAll()).toEqual(['entity1', 'entity2']); expect(mockRepository.find).toHaveBeenCalled(); }); // Other test cases... });
2. Integration Testing
Integration testing involves testing in an environment closer to production, which typically includes real database interactions.
Steps:
-
Launch a test database instance using Docker:
- Use Docker Compose to run a dedicated database instance for testing.
-
Configure TypeORM to connect to the test database:
- Set up TypeORM in the test environment to connect to the test database.
-
Write integration test cases:
- Write test cases to execute actual database operations.
- Verify that database operations yield expected results.
- Perform cleanup operations to maintain test independence and repeatability.
Example code:
typescriptdescribe('MyRepository Integration Tests', () => { let repository: MyRepository; beforeAll(async () => { const module: TestingModule = await Test.createTestingModule({ imports: [ TypeOrmModule.forRoot({ type: 'postgres', host: 'localhost', port: 5432, username: 'test', password: 'test', database: 'test_db', entities: [MyEntity], synchronize: true, }), TypeOrmModule.forFeature([MyEntity]), ], providers: [MyRepository], }).compile(); repository = module.get<MyRepository>(MyRepository); }); afterAll(async () => { // Close database connections and perform cleanup }); it('should create and retrieve an entity', async () => { await repository.save({ name: 'New Entity' }); const entity = await repository.findOne({ name: 'New Entity' }); expect(entity).toBeDefined(); expect(entity.name).toEqual('New Entity'); }); // Other integration test cases... });
By employing both methods (unit testing and integration testing), you can ensure your custom repositories perform reliably within NestJS/TypeORM applications.