Angular 角度单元测试:如何涵盖服务存根方法订阅中的活动
我正在为我的Angular component方法之一编写单元测试,该方法将服务调用的响应值分配给属性,并调用另一个方法 我用响应数据对服务进行了存根,并在测试中使用订阅中的expect语句对其进行订阅,但它始终将属性的值显示为空数组。我已经确认下面测试中的“response”包含模拟数据,但无法将组件属性“resultSet”显示为赋值。“toggleSearchForm()”方法的间谍似乎也从未被调用过 正在测试的方法: 搜索.component.tsAngular 角度单元测试:如何涵盖服务存根方法订阅中的活动,angular,jasmine,subscribe,rxjs-observables,Angular,Jasmine,Subscribe,Rxjs Observables,我正在为我的Angular component方法之一编写单元测试,该方法将服务调用的响应值分配给属性,并调用另一个方法 我用响应数据对服务进行了存根,并在测试中使用订阅中的expect语句对其进行订阅,但它始终将属性的值显示为空数组。我已经确认下面测试中的“response”包含模拟数据,但无法将组件属性“resultSet”显示为赋值。“toggleSearchForm()”方法的间谍似乎也从未被调用过 正在测试的方法: 搜索.component.ts submitSearchCriteri
submitSearchCriteria() {
this.searchService.searchRequest(this.myForm.value)
.pipe(take(1))
.subscribe(response => {
this.resultSet = response;
this.toggleSearchForm();
});
}
it('should assign resultSet to response data and trigger toggle', fakeAsync(() => {
const spy = spyOn(component, 'toggleSearchForm');
component.myForm.controls['field1'].setValue('some search query');
component.myForm.controls['field2'].setValue('something that narrows it down more');
searchServiceStub.searchRequest(component.myForm.value)
.subscribe(response => {
expect(component.resultSet).toContain(response);
expect(spy).toHaveBeenCalled();
expect(spy.calls.count()).toBe(1);
});
tick();
}))
...
const searchResults = require('./test-data/search-results.json');
searchRequest(searchCriteria) {
if (!searchCriteria) {
return of([])
}
return of(searchResults);
}
失败的测试:
search.component.spec.ts
submitSearchCriteria() {
this.searchService.searchRequest(this.myForm.value)
.pipe(take(1))
.subscribe(response => {
this.resultSet = response;
this.toggleSearchForm();
});
}
it('should assign resultSet to response data and trigger toggle', fakeAsync(() => {
const spy = spyOn(component, 'toggleSearchForm');
component.myForm.controls['field1'].setValue('some search query');
component.myForm.controls['field2'].setValue('something that narrows it down more');
searchServiceStub.searchRequest(component.myForm.value)
.subscribe(response => {
expect(component.resultSet).toContain(response);
expect(spy).toHaveBeenCalled();
expect(spy.calls.count()).toBe(1);
});
tick();
}))
...
const searchResults = require('./test-data/search-results.json');
searchRequest(searchCriteria) {
if (!searchCriteria) {
return of([])
}
return of(searchResults);
}
服务存根:
搜索服务.stub.ts
submitSearchCriteria() {
this.searchService.searchRequest(this.myForm.value)
.pipe(take(1))
.subscribe(response => {
this.resultSet = response;
this.toggleSearchForm();
});
}
it('should assign resultSet to response data and trigger toggle', fakeAsync(() => {
const spy = spyOn(component, 'toggleSearchForm');
component.myForm.controls['field1'].setValue('some search query');
component.myForm.controls['field2'].setValue('something that narrows it down more');
searchServiceStub.searchRequest(component.myForm.value)
.subscribe(response => {
expect(component.resultSet).toContain(response);
expect(spy).toHaveBeenCalled();
expect(spy.calls.count()).toBe(1);
});
tick();
}))
...
const searchResults = require('./test-data/search-results.json');
searchRequest(searchCriteria) {
if (!searchCriteria) {
return of([])
}
return of(searchResults);
}
我希望resultSet包含存根响应和已调用的spy,但测试失败,并显示以下错误消息:
Expected [ ] to contain [ Object({ thingName: 'thing i was searching for', thingId: 1234 }) ].
及
我认为如果您的组件测试像这样测试组件方法,那么它将更有意义
it('should assign resultSet to response data and trigger toggle', () => {
const spy = spyOn(component, 'toggleSearchForm');
const searchService = TestBed.get(SearchService) as SearchService;
const serviceSpy = spyOn(searchService, 'searchRequest').and.callThrough();
component.myForm.controls['field1'].setValue('some search query');
component.myForm.controls['field2'].setValue('something that narrows it down more');
component.submitSearchCriteria();
expect(component.resultSet).toEqual([{ thingName: 'thing i was searching for', thingId: 1234 }]);
expect(serviceSpy).toHaveBeenCalledWith(component.myForm.value);
expect(spy.calls.count()).toBe(1);
});
要使其正常工作,您的配置应该如下所示
TestBed.configureTestingModule({
declarations: [SearchComponent],
providers: [{provide: SearchService, useClass: SearchServiceStub}],
imports: [ReactiveFormsModule],
})
需要注意的重要变化:
- 要检查调用了什么服务,可以在测试静态结果是否与输入匹配之前检查新的serviceSpy
- 搜索结果我们将比较来自
搜索结果.json的内容,因为这是您的搜索服务返回的内容
- 不再订阅您的
,我们现在调用它而不是您的存根服务组件。submitSearchCriteria
it('should assign resultSet to response data and trigger toggle', () => {
const spy = spyOn(component, 'toggleSearchForm');
const searchService = TestBed.get(SearchService) as SearchService;
const serviceSpy = spyOn(searchService, 'searchRequest').and.callThrough();
component.myForm.controls['field1'].setValue('some search query');
component.myForm.controls['field2'].setValue('something that narrows it down more');
component.submitSearchCriteria();
expect(component.resultSet).toEqual([{ thingName: 'thing i was searching for', thingId: 1234 }]);
expect(serviceSpy).toHaveBeenCalledWith(component.myForm.value);
expect(spy.calls.count()).toBe(1);
});
要使其正常工作,您的配置应该如下所示
TestBed.configureTestingModule({
declarations: [SearchComponent],
providers: [{provide: SearchService, useClass: SearchServiceStub}],
imports: [ReactiveFormsModule],
})
需要注意的重要变化:
- 要检查调用了什么服务,可以在测试静态结果是否与输入匹配之前检查新的serviceSpy
- 搜索结果我们将比较来自
搜索结果.json的内容,因为这是您的搜索服务返回的内容
- 不再订阅您的
,我们现在调用它而不是您的存根服务组件。submitSearchCriteria