我正在尝试间谍并拦截我在组件测试中使用的服务方法:
这是我试图测试的组件:
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
”,但是间谍似乎仍然没有拦截函数调用
答案 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()
之前创建间谍