我一直在尝试为我的角度组件编写单元测试。目前,在我的服务调用中,为了获取我的组件的数据,我有一个可观察的,一旦调用完成,就会被确认为真。在我的组件中可以观察到这一点,这样组件就知道调用什么时候完成了。我已经成功地模拟了组件中对数据的调用,但我很难找到一种方法来模拟单个可观察的值。
所有问题都是关于模拟组件中服务中的函数调用的,但是没有一个问题是关于模拟单个可观察的函数调用的。
这是我在服务中的函数调用。如您所见,一旦finalize函数运行,就会给可观察到的值一个新的值:
public getSmallInfoPanel(key: string): BehaviorSubject<InfoPanelResponse> {
if (key) {
this.infoPanel = new BehaviorSubject<InfoPanelResponse>(null);
this.http.get(`${this.apiUrl}api/Panels/GetInfoPanel/${key}`).pipe(
retry(3),
finalize(() => {
this.hasLoadedSubject.next(true);
}))
.subscribe((x: InfoPanelResponse) => this.infoPanel.next(x));
}
return this.infoPanel;
}下面是我如何在服务中创建Observable:
private hasLoadedSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
public hasLoadedObs: Observable<boolean> = this.hasLoadedSubject.asObservable();然后在我的组件中,我订阅了从Observable创建的BehaviourSubject
public hasLoaded: boolean;
ngOnInit() {
this.infoPanelSmallService.hasLoadedObs.subscribe(z => this.hasLoaded = z);
}当我运行ng test时,组件测试失败,因为它不知道hasLoadedObs是什么,所以它不能订阅它。
如果我能提供更多的信息,请告诉我。谢谢。
更新1
describe('InformationPanelSmallComponent', () => {
let component: InformationPanelSmallComponent;
let fixture: ComponentFixture<InformationPanelSmallComponent>;
let mockInfoPanelService;
let mockInfoPanel: InfoPanel;
let mockInfoPanelResponse: InfoPanelResponse;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule,
FontAwesomeModule,
HttpClientTestingModule
],
declarations: [InformationPanelSmallComponent, CmsInfoDirective],
providers: [
{ provide: InfoPanelSmallService, useValue: mockInfoPanelService }
]
})
.compileComponents();
}));
beforeEach(() => {
mockInfoPanel = {
Title: 'some title',
Heading: 'some heading',
Description: 'some description',
ButtonText: 'some button text',
ButtonUrl: 'some button url',
ImageUrl: 'some image url',
Key: 'test-key',
SearchUrl: '',
VideoUrl: ''
}
mockInfoPanelResponse = {
InfoPanel: mockInfoPanel
}
fixture = TestBed.createComponent(InformationPanelSmallComponent);
component = fixture.componentInstance;
mockInfoPanelService = jasmine.createSpyObj(['getSmallInfoPanel']);
component = new InformationPanelSmallComponent(mockInfoPanelService);
component.key = "test-key"
});
it('should create', () => {
expect(component).toBeTruthy();
});
//TO DO
it('should get info panel from info panel service', () => {
mockInfoPanelService.getSmallInfoPanel.and.returnValue(of(mockInfoPanelResponse));
component.ngOnInit();
expect(mockInfoPanelService.getSmallInfoPanel).toHaveBeenCalled();
expect(component.infoPanel).toEqual(mockInfoPanel);
});
});发布于 2019-05-28 09:32:09
我发现这与我模拟服务和创建组件的顺序有关。我还使用了TestBed.overrideProvider,这与我在上面使用的不同。这是最终生成的测试文件:
describe('InformationPanelSmallComponent', () => {
let component: InformationPanelSmallComponent;
let fixture: ComponentFixture<InformationPanelSmallComponent>;
let mockInfoPanelService;
let mockInfoPanel: InfoPanel;
let mockInfoPanelResponse: InfoPanelResponse;
beforeEach(async(() => {
mockInfoPanelService = jasmine.createSpyObj(['getSmallInfoPanel', 'hasLoadedObs']);
TestBed.configureTestingModule({
imports: [
RouterTestingModule,
FontAwesomeModule,
HttpClientTestingModule
],
declarations: [InformationPanelSmallComponent, CmsInfoDirective, UrlRedirectDirective],
providers: [
{ provide: 'BASE_URL', useValue: '/' },
{ provide: 'API_URL', useValue: '/' }
]
})
TestBed.overrideProvider(InfoPanelSmallService, { useValue: mockInfoPanelService });
TestBed.compileComponents();
}));
beforeEach(() => {
mockInfoPanel = {
Title: 'some title',
Heading: 'some heading',
Description: 'some description',
ButtonText: 'some button text',
ButtonUrl: 'some button url',
ImageUrl: 'some image url',
Key: 'test-key',
SearchUrl: '',
VideoUrl: ''
}
mockInfoPanelResponse = {
InfoPanel: mockInfoPanel
}
fixture = TestBed.createComponent(InformationPanelSmallComponent);
component = fixture.componentInstance;
mockInfoPanelService.getSmallInfoPanel.and.returnValue(of(mockInfoPanelResponse));
mockInfoPanelService.hasLoadedObs = of(true);
component.key = "test-key"
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
describe('ngOnInit', () => {
it('should get info panel from info panel service', () => {
expect(component.hasLoaded).toEqual(true);
expect(mockInfoPanelService.getSmallInfoPanel).toHaveBeenCalled();
expect(component.infoPanel).toEqual(mockInfoPanel);
});
it('should get loaded is true from service', () => {
expect(component.hasLoaded).toEqual(true);
});
});
});然后,我没有得到更多的错误,测试实际上是正确的。谢谢@RuiMarques和其他人的所有投入。
https://stackoverflow.com/questions/55968888
复制相似问题