Имитирующая служба в компоненте — макет игнорируется

#angular #service #mocking #angular2-testing

#angular #Обслуживание #издевательство #angular2-тестирование

Вопрос:

На этот раз я пытаюсь смоделировать службу (которая выполняет http-вызовы) для тестирования компонента.

 @Component({
  selector: 'ub-funding-plan',
  templateUrl: './funding-plan.component.html',
  styleUrls: ['./funding-plan.component.css'],
  providers: [FundingPlanService]
})
export class FundingPlanComponent implements OnInit {
  constructor(private fundingPlanService: FundingPlanService) {
  }

  ngOnInit() {
    this.reloadFundingPlans();
  }

  reloadFundingPlans() {
    this.fundingPlanService.getFundingPlans().subscribe((fundingPlans: FundingPlan[]) => {
      this.fundingPlans = fundingPlans;
    }, (error) => {
      console.log(error);
    });
  }
}
 

В документации (версия 2.0.0) объясняется, что вы должны издеваться над сервисом. Используя ту же TestBed конфигурацию:

 describe('Component: FundingPlan', () => {
  class FundingPlanServiceMock {
    getFundingPlans(): Observable<FundingPlan> { return Observable.of(testFundingPlans) }
  }

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [FundingPlanComponent],
      providers: [
        { provide: FundingPlanService, useClass: FundingPlanServiceMock },
      ]
    });

    fixture = TestBed.createComponent(FundingPlanComponent);
    component = fixture.componentInstance;
  });

  fit('should display a title', () => {
    fixture.detectChanges();
    expect(titleElement.nativeElement.textContent).toContain('Funding Plans');
  });

});
 

Когда я запускаю тест, я получаю:

 Error: No provider for AuthHttp!
 

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

Любой совет? Спасибо!

Ответ №1:

Это из-за

 @Component({
  providers: [FundingPlanService] <===
})
 

@Component.providers Имеет приоритет над любыми глобальными поставщиками, поскольку использование @Component.providers делает поставщика ограниченным только для компонента. В тесте Angular создает имитируемую службу в области модуля и исходную службу в области компонента.

Чтобы решить эту проблему, Angular предоставляет TestBed.overrideComponent метод, с помощью которого мы можем переопределять такие вещи, как шаблоны и поставщики на уровне компонентов.

 TestBed.configureTestingModule({
  declarations: [FundingPlanComponent]
});
TestBed.overrideComponent(FundingPlanComponent, {
  set: {
    providers: [
      { provide: FundingPlanService, useClass: FundingPlanServiceMock },
    ]
  }
})
 

Смотрите также:

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

1. Предоставленная ссылка была бы чрезвычайно полезной, но она немного повреждена. Вы имели в виду это? Переопределение поставщика компонента

2. Пожалуйста, обратите внимание, что для того, чтобы получить экземпляр mocked service (например, шпионить за его методами) вместо использования TestBed.inject(FundingPlanService) , вам нужно будет сделать это следующим образом fundingPlanService = <any>fixture.debugElement.injector.get(FundingPlanService);