Внедрить репозиторий TypeORM в сервис NestJS для проверки фиктивных данных - PullRequest
8 голосов
/ 26 марта 2019

В этом выпуске .

. 1004 * есть длинная дискуссия о том, как это сделать. Я экспериментировал с рядом предложенных решений, но мне не повезло.

Может ли кто-нибудь привести конкретный пример того, как протестировать сервис с внедренным хранилищем и фиктивными данными?

Ответы [ 2 ]

11 голосов
/ 27 марта 2019

Предположим, у нас есть очень простой сервис, который находит пользовательскую сущность по идентификатору:

export class UserService {
  constructor(@InjectRepository(UserEntity) private userRepository: Repository<UserEntity>) {
  }

  async findUser(userId: string): Promise<UserEntity> {
    return this.userRepository.findOne(userId);
  }
}

Затем вы можете смоделировать UserRepository с помощью следующей фабрики макетов (при необходимости добавьте больше методов):

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

Использование фабрики гарантирует, что новый макет будет использоваться для каждого теста.

describe('UserService', () => {
  let service: UserService;
  let repositoryMock: MockType<Repository<UserEntity>>;

  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>(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);
  });
});

Для безопасности и комфорта типов вы можете использовать следующую типизацию для макетов (далеко не идеально,может быть лучшее решение, когда Jest сам начнет использовать машинопись в следующих основных выпусках):

export type MockType<T> = {
  [P in keyof T]: jest.Mock<{}>;
};
1 голос
/ 19 июня 2019

Я также обнаружил, что это работает для меня:

export const mockRepository = jest.fn(() => ({
  metadata: {
    columns: [],
    relations: [],
  },
}));

и

const module: TestingModule = await Test.createTestingModule({
      providers: [{ provide: getRepositoryToken(Entity), useClass: mockRepository }],
    }).compile();
...