Как имитировать стороннюю библиотеку с помощью jest

Я разрабатываю node.js приложение, используя nestjs. У меня есть класс LoggerService, как показано ниже.

export class LoggerService {

    private logger: Rollbar;

    constructor() {
        this.logger = this.setupLogger();
    }

    critical(...args: Array<string | Error | object | Date | any[]>) {
        this.logger.error(...args);
    }

    private setupLogger(): Rollbar {
        if (this.logger == null) {

            this.logger = new Rollbar({
                accessToken: 'token',
                environment: 'dev',
                captureUncaught: true,
                captureUnhandledRejections: true,
            });

        }

        return this.logger;
    }

Теперь я пишу модульный тест для этого класса, используя шутку, как показано ниже.

describe('LoggerService.log', () => {
  let service: LoggerService;

  beforeEach(async () => {

    const module: TestingModule = await Test.createTestingModule({
      providers: [LoggerService],
    }).compile();

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

  it('critical', () => {
    service.critical('error','message');
    expect(???).toHaveBeenCalledWith('error', 'message')
  })

);

Мой вопрос в том, как проверить (ожидать), вызывается ли logger.error, или как издеваться над Rollbar в этом классе.


person Reza    schedule 06.08.2019    source источник


Ответы (1)


1) Предоставьте вашу внешнюю зависимость / библиотеку в качестве вводимого токена в вашем модуле

@Module({
  providers: [
    {
      provide: 'Rollbar',
      useFactory: async (configService: ConfigService) => new Rollbar({
                accessToken: configService.accessToken,
                environment: configService.environment,
                captureUncaught: true,
                captureUnhandledRejections: true,
            }),
      inject: [ConfigService],
    },
  ]

2) Вставьте его в свой LoggerService вместо того, чтобы создавать его

export class LoggerService {
    constructor(@Inject('Rollbar') private logger: Rollbar) {
    }

3) Теперь вы можете издеваться над своей зависимостью в своем тесте.

const module: TestingModule = await Test.createTestingModule({
  providers: [
    LoggerService,
    { provide: 'Rollbar', useFactory: rollbarMockFactory },
  ],
}).compile();
person Kim Kern    schedule 06.08.2019
comment
Замечательно, только одно, где определяется rollbarMockFactory? - person Reza; 06.08.2019
comment
Рад, что ты нашел это полезным. :-) Это просто заполнитель. Если вы хотите узнать больше о насмешках, загляните в эту ветку: stackoverflow.com/a/55366343/4694994 - person Kim Kern; 06.08.2019
comment
Я сделал это, и в моем тесте мой код похож на const module: TestingModule = await Test.createTestingModule({ providers: [ LoggerService, { provide: 'Rollbar', useFactory: jest.fn(() => ({ error: jest.fn(() => null), })) } ], }), но я получаю эту ошибку: «Nest не может разрешить зависимости LoggerService (?). Убедитесь, что аргумент с индексом [0] доступен в контексте _RootTestModule`, и это моя служба constructor(@Inject('Rollbar') private logger: Rollbar) { } - person Reza; 06.08.2019
comment
Сервер запускается? Кстати: вы не должны использовать простую строку в качестве токена в продакшене. Определите константу для вашего токена инъекции. Обязательно убедитесь, что ваши жетоны везде одинаковые. - person Kim Kern; 06.08.2019
comment
я тоже это сделал, все тот же `.overrideProvider ('Rollbar') .useFactory ({factory: () =› ({error: jest.fn (() = ›null),})})` - person Reza; 06.08.2019
comment
а также этот `провайдеры: [LoggerService, {provide: 'Rollbar', useValue: {error: jest.fn (() =› null),}}], ` - person Reza; 06.08.2019
comment
Ммм, я не знаю, почему это не работает для вас, это работает в моем коде. : - | Возможно, имеет какое-то отношение к github.com/nestjs/nest/issues/412# issuecomment-366076180? - person Kim Kern; 06.08.2019
comment
Также есть несколько ошибок, связанных с токенами инъекций. Возможно, попробуйте обновить свои зависимости: github.com/nestjs/nest/issues/2379 - person Kim Kern; 06.08.2019
comment
Я использую последнюю версию 6.5.3;) - person Reza; 06.08.2019
comment
Я отправил ошибку в их репо, github.com/nestjs/nest/issues/2713 - person Reza; 06.08.2019
comment
Кстати, я отмечу ваш ответ как ответ, так как это правильное направление - person Reza; 06.08.2019
comment
В качестве обходного пути вы можете просто создать службу вручную в своем тесте с помощью new LoggerService(rollbarMock). Вам не нужны инструменты TestingModule в модульном тесте, см. github.com/ nestjs / nest / issues / 1786 # issuecomment-475585609 - person Kim Kern; 06.08.2019
comment
Это была моя ошибка, у меня было 2 describe, я изменил 1, а ошибка была из второй; DDDD - person Reza; 06.08.2019
comment
Не могли бы вы также взглянуть на этот вопрос stackoverflow.com/questions/57383233/ - person Reza; 06.08.2019