Karma Jasmine — использовать метод обслуживания из компонента

#angular #karma-jasmine

#angular #karma-jasmine

Вопрос:

В моем компоненте есть следующий код:

 ngOnInit() {
    this.formattedPacks = this.protocolPackService.formatPacks(this.selectedPacks);
}
  

В моем тесте я получаю следующую ошибку:

 this.protocolPackService.formatPacks is not a function
  

formatPacks Метод является вспомогательной функцией без какого-либо запроса сервера, который возвращает массив. Я не хочу, чтобы он вел себя как любой другой метод обслуживания, который я должен отслеживать и издеваться над результатом.

Я тоже могу издеваться formatPacks , но я использую его в двух разных тестах, и он должен выдавать разные результаты для каждого.

Как я могу убедиться, что он правильно выполнен в моем тесте?

Я издеваюсь над другими protocolPackService методами (вызовами API) в своем тесте следующим образом:

 const ppackService = jasmine.createSpyObj('ProtocolPackService', ['listPacks', 'findPackDevices']);

    const packListResult = '{}';
    const packDevicesResult = '{}';

    const getPackListSpy = ppackService.listPacks.and.returnValue( Promise.resolve(packListResult) );
    const findPackDevicesSpy = ppackService.findPackDevices.and.returnValue( of(packDevicesResult) );
  

в моих провайдерах:

 providers: [
            { provide: ProtocolPackService, useValue: ppackService },
            ToastService]
  

Комментарии:

1. Вы издевались protocolPackService над тестами или используете useValue для предоставления типа , запрошенного для переменной protocolPackService ?

2. @Ankesh добавил код, который я использую, я издевался над ним в тестах, а также использовал useValue

3. @TheUnreal Сработал ли мой ответ?

Ответ №1:

Согласно упомянутым деталям, если вам нужно использовать оригинальный метод для formatPacks , вам необходимо создать отдельный экземпляр для этой зависимости, а затем использовать его в своем тесте.

Попробуйте это для своих тестов

 beforeEach(
  "...",
  inject([ProtocolPackService], protoPackService => {
    ppackService = jasmine.createSpyObj("ProtocolPackService", {
      listPacks: () => {},
      findPackDevices: () => {},
      formatPacks: packs => {
        protoPackService.formatPacks(packs);
      },
    });
  }),
);
  

Комментарии:

1. Не уверен, что этот код вносит какие-либо изменения, если я удалю ‘formatPacks’ из моих createSpyObj методов и размещу ваш код, я получу this.protocolPackService.formatPacks is not a function . Один из методов компонента вызывает этот метод обслуживания, а не тест.

2. Позвольте мне связаться с компьютером, чтобы разобраться в этой ошибке.

Ответ №2:

Хорошо, итак, проблема с вашим подходом заключается в том, что вам нужно использовать useClass и создать заглушку:

 
class PpackServiceStub{
    formatPacks(){
      // return whatever you are expecting, be it promise or Observable using of()
    }
    // create other methods similary with expected Output
  }

  

и в providers

 providers: [
  { provide: ProtocolPackService, useClass: PpackServiceStub },
    ToastService
   ]

  

Теперь, давайте предположим, что вы хотите проверить 2 разных поведения сервиса, затем вам нужно создать spy . Я возьму пример функции checkIfHuman() , поэтому я добавлю:

 
class PpackServiceStub{
    formatPacks(){
      // return whatever you are expecting, be it promise or Observable using of()
    }
    checkIfHuman(){
      return of({val : true})
    }
  }

  

с component.ts кодом как что-то вроде:

 ngOnInit() {    
  this.protocolPackService.checkIfHuman().subscribe(res =>  
   { 
    this.humanFlag =  res.val
   })
}
  

сделайте protocolPackService как public в component конструкторе, чтобы мы могли просматривать spec файл, как показано ниже:

   it('On ngOnInit should assign value as TRUE', () => {
    spyOn(component.protocolPackService, 'checkIfHuman').and.returnValue(of({val: true}));
    // you dont even need to create this spy because you already have the same value being returned in "PpackServiceStub" 
    component.ngOnInit();
    expect(component.humanFlag).toBeTruthy();    
  });

  it('On ngOnInit should assign value as FALSE', () => {
    spyOn(component.protocolPackService, 'checkIfHuman').and.returnValue(of({val: false}));
    component.ngOnInit();
    expect(component.humanFlag).toBeFalsy();    
  });

  

Ответ №3:

Поскольку вы создаете заглушку для ProtocolPackService которой является ppackService , тест ожидает, что пакеты формата будут присутствовать в ppackService . То есть вы должны явно создать его. Если вы предоставляете услугу в модуле, она будет использоваться во всех компонентах, импортированных в этот модуль.