0

我正在为我的一个 Angular 组件方法编写单元测试,该方法为一个属性分配来自服务调用的响应值并调用另一个方法。

我的服务带有响应数据,我在测试中使用订阅中的期望语句订阅它,但它一直将属性的值显示为空数组。我已经确认下面测试中的“响应”包含模拟数据,但无法让组件属性“resultSet”显示为分配的值。“toggleSearchForm()”方法的间谍似乎也从未被调用过。

被测试的方法: search.component.ts

submitSearchCriteria() {
    this.searchService.searchRequest(this.myForm.value)
        .pipe(take(1))
        .subscribe(response => {
            this.resultSet = response;
            this.toggleSearchForm();
        });
}

失败的测试: search.component.spec.ts

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();
}))

服务存根: search-service.stub.ts

...
const searchResults = require('./test-data/search-results.json');

searchRequest(searchCriteria) {
    if (!searchCriteria) {
        return of([])
    }
    return of(searchResults);
}

我希望 resultSet 包含存根响应和已调用的间谍,但测试失败并显示以下错误消息:

Expected [  ] to contain [ Object({ thingName: 'thing i was searching for', thingId: 1234 }) ].

Error: Expected spy toggleSearchForm to have been called.
4

1 回答 1

2

我认为如果像这样测试组件方法,您的组件测试会更有意义。

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
  • 我们将比较来自您的搜索结果,search-results.json因为这是您的搜索服务返回的结果
  • 不再订阅,因为发生在你的component.submitSearchCriteria,我们现在调用它而不是你的存根服务
于 2019-09-13T03:03:07.723 回答