Reputation: 953
I'm writing unit tests for one of my Angular component methods which assigns a property the response value from a service call and calls another method.
I have my service stubbed with response data and I subscribe to it inside my test with the expect statements inside the subscription but it keeps showing the value of the property as being an empty array. I've confirmed the "response" in the test below contains the mock data but cannot get the component property "resultSet" to show as assigned a value. The spy for the "toggleSearchForm()" method never appears to be called either.
The method being tested: search.component.ts
submitSearchCriteria() {
this.searchService.searchRequest(this.myForm.value)
.pipe(take(1))
.subscribe(response => {
this.resultSet = response;
this.toggleSearchForm();
});
}
The failing test: 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();
}))
The service stub: search-service.stub.ts
...
const searchResults = require('./test-data/search-results.json');
searchRequest(searchCriteria) {
if (!searchCriteria) {
return of([])
}
return of(searchResults);
}
I expect resultSet to contain the stub response and the spy to have been called but the test fails with the following error messages:
Expected [ ] to contain [ Object({ thingName: 'thing i was searching for', thingId: 1234 }) ].
and
Error: Expected spy toggleSearchForm to have been called.
Upvotes: 0
Views: 1567
Reputation: 1264
I think your component test would be more meaningful if it tested the component method like so.
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);
});
To make this work, your configuration should look something like
TestBed.configureTestingModule({
declarations: [SearchComponent],
providers: [{provide: SearchService, useClass: SearchServiceStub}],
imports: [ReactiveFormsModule],
})
Important changes to note:
search-results.json
since that is what your search service is returningcomponent.submitSearchCriteria
, which we're now calling instead of your stub serviceUpvotes: 2