Angular Модульный тест, если Компонент вызывает метод Http Service: Ошибка: <spyOn>: не удалось найти объект для шпионажа - PullRequest
1 голос
/ 10 апреля 2020

Я собираюсь проверить, вызывает ли метод компонента метод обслуживания. Реализация метода сервиса - это Post, однако меня не интересуют механизмы post, так как я планирую проверить это в сервисе, скорее я просто хочу знать, был ли вызван правильный метод сервиса.

Я новичок в модульном тестировании, однако ошибка указывает на использование spyon следующим образом. Использование spyOn ('object, methodName'), указывающее, что я не создаю должным образом экземпляр объекта службы для тестирования, однако в Чтобы создать объект службы, требуется HttpClient в конструкторе, я пробовал так много решений, и я часами читал на этом этапе, помощь будет очень признателен.

Best, S C

Юнит-тест

describe('SchedulerComponent', () => {
  let component : SchedulerComponent;
  let fixture : ComponentFixture<SchedulerComponent>;
  let schedulerReportService : SchedulerReportService;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ SchedulerComponent ],
      imports: [BrowserAnimationsModule,
                MatSlideToggleModule,
                MatRadioModule,
                MatFormFieldModule,
                MatInputModule,
                MatSelectModule,
                MatNativeDateModule,
                MatDatepickerModule,
                NativeDateModule,
                NgxMaterialTimepickerModule,
                ReactiveFormsModule,
                FormsModule,
                HttpClientTestingModule],
      schemas:[CUSTOM_ELEMENTS_SCHEMA],
      providers: [{provide : SchedulerReportService}]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(SchedulerComponent);
    component = fixture.componentInstance;

    fixture.detectChanges();
  });

  fit('onSubmit should call scheduleReportService',inject([SchedulerReportService], (service: SchedulerReportService) => {

    let scheduleServiceSpy = spyOn(schedulerReportService, 'submitScheduledReport') ;
    let submitReportSpy = spyOn(component, 'onSubmit'); 

    submitReportSpy.and.callThrough();

    expect(scheduleServiceSpy).toHaveBeenCalled();


  }))

Соответствующий сервисный код выглядит следующим образом:

@Injectable({
  providedIn: 'root'
})
export class SchedulerReportService {

  constructor(private http: HttpClient) { }

   submitScheduledReport(servicerequest: ScheduleService) {

    console.log(servicerequest)

    // const headers = new HttpHeaders({'key':'value'});
    // return this.http.post<ScheduleService>(localUrl, servicerequest, {headers : headers} ).pipe(
    //   retry(1), catchError(this.handleError<ScheduleService>('scheduled report post error')));

  }

Компонент содержит метод для запуска сервиса

export class SchedulerComponent implements OnInit {

  constructor(private fb: FormBuilder,
              private schedulerReportService: SchedulerReportService) { 
    onSubmit(){

    let report = this.schedulerForm.value;
    let scheduleServiceModel = new ScheduleService(report)
    this.schedulerReportService.submitScheduledReport(scheduleServiceModel);

  }
}

1 Ответ

1 голос
/ 10 апреля 2020

Чтобы конкретно решить проблему в приведенном выше коде, вам нужно установить экземпляр службы перед вызовом spyOn. Примерно так:

 schedulerReportService = fixture.debugElement.injector.get(SchedulerReportService);

  ...

 let scheduleServiceSpy = spyOn(schedulerReportService, submitScheduledReport');

Однако я рекомендую другой способ сделать это, используя служебную шпионскую заглушку. Поскольку вам не нужно тестировать свою службу, только при вызове метода службы вам не нужно вводить исходный SchedulerReportService, вместо этого вы можете предоставить шпиону объекта службы Angular следующим образом:

describe('SchedulerComponent', () => {
  let component : SchedulerComponent;
  let fixture : ComponentFixture<SchedulerComponent>;
  let schedulerReportService = jasmine.createSpyObj('SchedulerReportService', ['submitScheduledReport']);

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ SchedulerComponent ],
      imports: [BrowserAnimationsModule,
                MatSlideToggleModule,
                MatRadioModule,
                MatFormFieldModule,
                MatInputModule,
                MatSelectModule,
                MatNativeDateModule,
                MatDatepickerModule,
                NativeDateModule,
                NgxMaterialTimepickerModule,
                ReactiveFormsModule,
                FormsModule,
                HttpClientTestingModule],
      schemas:[CUSTOM_ELEMENTS_SCHEMA],
      providers: [{provide : SchedulerReportService, useValue: schedulerReportService}]
    })
    .compileComponents();

    fixture = TestBed.createComponent(SchedulerComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  }));

  it('onSubmit should call scheduleReportService', () => {
    component.onSubmit();
    expect(schedulerReportService.submitScheduledReport).toHaveBeenCalled();
  }));

Таким образом, вы можете проверить, что schedulerReportService.submitScheduledReport был вызван без издержек исходных вызовов http службы.

...