无法监视角度4中注入服务的方法

时间:2018-04-12 15:53:59

标签: angular unit-testing jasmine karma-jasmine

我正在尝试间谍并拦截我在组件测试中使用的服务方法:

这是我试图测试的组件:

export class SearchModuleCheckCardListComponent implements OnInit {
    httpError: boolean = false;


  constructor(private searchModuleService: SearchModuleService) {
    console.log("Constructor");
  }

  ngOnInit() {
    this.fetchSearchModule();
  }



  /**
   * Get all search modules from the back end service
   */
  fetchSearchModule() {
    console.log("FetchSearchModule");
    this.searchModuleService.fetchSearchModules().subscribe(searchModules => 
    {
      //Most code abstracted out for simplicity
      this.httpError = false;
    }, err => {
      this.httpError = true;
    })
  }

基本上我要测试的是设置属性 httpError ,这是我的spec文件的样子:(再次删除不相关的代码)

describe('SearchModuleCheckCardListComponent', () => {
  let component: SearchModuleCheckCardListComponent;
  let fixture: ComponentFixture<SearchModuleCheckCardListComponent>;
  let searchModuleService: SearchModuleServiceStub;



  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
                      SearchModuleCheckCardListComponent,
                    ],
      providers:    [
                      { provide: SearchModuleService, useClass: SearchModuleServiceStub },
                    ]
    })
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(SearchModuleCheckCardListComponent);
    component = fixture.componentInstance;
    searchModuleService = fixture.debugElement.injector.get(SearchModuleService);
    fixture.detectChanges();
  });

it('should set httpError on error', () => {
    spyOn(searchModuleService, 'fetchSearchModules').and.returnValue(Observable.throw('error'));

    //'Trying to test:'expect(component.httpError).toBeTruthy();

    //This fails  inspite of fetchSearchModules being called in the stub
    expect(searchModuleService.fetchSearchModules).toHaveBeenCalled();
  })
}); 

这就是searchModuleServiceStub的样子:

export class SearchModuleServiceStub {


  constructor() {}


  fetchSearchModules(): Observable<SearchModule[]> {
    console.log('fetchSearchModules Called');
    return Observable.of(SEARCH_MODULES);
  }
}

现在,当我运行测试时,控制台会注销“fetchSearchModules Called”,但是间谍似乎仍然没有拦截函数调用

6 个答案:

答案 0 :(得分:1)

好像我必须明确地调用ngOnInit();这就是我做的工作:

 it('should set httpError on error', () => {
    spyOn(searchModuleService, 'fetchSearchModules').and.returnValue(Observable.throw('error'));
    component.ngOnInit();
    expect(component.httpError).toBeTruthy();
  })

答案 1 :(得分:0)

尝试切换到TestBed.get(SearchModuleService),您无需将其从debugElement中删除。

答案 2 :(得分:0)

fixture.detectChanges的调用阻碍了您的ngOnInit测试。来自角度测试指南:

  

延迟变化检测是有意和有用的。它使测试人员有机会在Angular启动数据绑定并调用生命周期钩子之前检查和更改组件的状态。

因此,当您设置间谍时,已经调用了ngOnInit,并且您的测试将不会重新调用它。这就是你对ngOnInit的额外调用导致它工作的原因。

在间谍设置之后移动fixture.detectChanges()调用应该让您的测试正常运行,并且是一个更正确的测试。

答案 3 :(得分:0)

使用jasmine的toThrowError间谍方法。

jefb.setSerializer(new Jackson2ExecutionContextStringSerializer());

答案 4 :(得分:0)

您的问题似乎与您未在测试中注入服务以便窥探,重构您的测试这一事实有关

it('should set httpError on error', inject([SearchModuleService], (searchModuleService: SearchModuleService) => {
     spyOn(searchModuleService, 'fetchSearchModules').and.returnValue(Observable.throw('error'));

     //'Trying to test:'expect(component.httpError).toBeTruthy();

    //This fails  inspite of fetchSearchModules being called in the stub
     expect(searchModuleService.fetchSearchModules).toHaveBeenCalled();
   })
}));

让我知道是否有作品

答案 5 :(得分:0)

这是因为在创建间谍之前会触发<v-list class="table pa-0"> <v-list-tile v-for="(element, index) in elements" :key="`pricing_table_element_${index}`" :class="{'dark-background': index % 2 === 0}" avatar > <v-list-tile-avatar> <fa-icon icon="check-circle" color="#00BB9B" /> </v-list-tile-avatar> <v-list-tile-content> {{ element.content }} </v-list-tile-content> <v-list-tile-action> <v-tooltip right> <fa-icon slot="activator" icon="info-circle" color="#f68e28" /> <span>{{ element.tooltip }}</span> </v-tooltip> </v-list-tile-action> </v-list-tile> </v-list>生命周期挂钩。因此,该函数在间谍不知道的情况下被调用。

您有两个选择:

1)在创建间谍之后,在测试中重新触发ngOnInit()
2)之前在您的ngOninit()

中呼叫TestBed.createComponent()之前创建间谍