Inject TypeORM repository into NestJS service for mock data testing

前端 未结 3 1788
借酒劲吻你
借酒劲吻你 2020-11-27 18:12

There\'s a longish discussion about how to do this in this issue.

I\'ve experimented with a number of the proposed solutions but I\'m not having much luck.

C

3条回答
  •  旧巷少年郎
    2020-11-27 18:31

    Let's assume we have a very simple service that finds a user entity by id:

    export class UserService {
      constructor(@InjectRepository(UserEntity) private userRepository: Repository) {
      }
    
      async findUser(userId: string): Promise {
        return this.userRepository.findOne(userId);
      }
    }
    

    Then you can mock the UserRepository with the following mock factory (add more methods as needed):

    // @ts-ignore
    export const repositoryMockFactory: () => MockType> = jest.fn(() => ({
      findOne: jest.fn(entity => entity),
      // ...
    }));
    

    Using a factory ensures that a new mock is used for every test.

    describe('UserService', () => {
      let service: UserService;
      let repositoryMock: MockType>;
    
      beforeEach(async () => {
        const module: TestingModule = await Test.createTestingModule({
          providers: [
            UserService,
            // Provide your mock instead of the actual repository
            { provide: getRepositoryToken(UserEntity), useFactory: repositoryMockFactory },
          ],
        }).compile();
        service = module.get(UserService);
        repositoryMock = module.get(getRepositoryToken(UserEntity));
      });
    
      it('should find a user', async () => {
        const user = {name: 'Alni', id: '123'};
        // Now you can control the return value of your mock's methods
        repositoryMock.findOne.mockReturnValue(user);
        expect(service.findUser(user.id)).toEqual(user);
        // And make assertions on how often and with what params your mock's methods are called
        expect(repositoryMock.findOne).toHaveBeenCalledWith(user.id);
      });
    });
    

    For type safety and comfort you can use the following typing for your mocks (far from perfect, there might be a better solution when jest itself starts using typescript in the upcoming major releases):

    export type MockType = {
      [P in keyof T]: jest.Mock<{}>;
    };
    

提交回复
热议问题