So I'm learning how to test services in Angular and I tried to copy the below example in the Angular docs.
let httpClientSpy: { get: jasmine.Spy }; let heroService: HeroService; beforeEach(() => { // TODO: spy on other methods too httpClientSpy = jasmine.createSpyObj('HttpClient', ['get']); heroService = new HeroService(<any> httpClientSpy); }); it('should return expected heroes (HttpClient called once)', () => { const expectedHeroes: Hero[] = [{ id: 1, name: 'A' }, { id: 2, name: 'B' }]; httpClientSpy.get.and.returnValue(asyncData(expectedHeroes)); heroService.getHeroes().subscribe( heroes => expect(heroes).toEqual(expectedHeroes, 'expected heroes'), fail ); expect(httpClientSpy.get.calls.count()).toBe(1, 'one call'); });
I tried to copy it quite literally, but it gives me the following error:
ERROR in src/app/services/find-locals.service.spec.ts(17,38): error TS2304: Cannot find name 'asyncData'.
Can someone help me with replacing this? Or telling me where I might have done something wrong elsewhere?
Here is the test file that copied from the Angular docs:
import {FindLocalsService} from './find-locals.service'; import {HttpClient, HttpClientModule} from '@angular/common/http'; let findLocalsService: FindLocalsService; let httpClientSpy: { get: jasmine.Spy, post: jasmine.Spy }; beforeEach(() => { httpClientSpy = jasmine.createSpyObj('HttpClient', ['get', 'post']); findLocalsService = new FindLocalsService(<any> httpClientSpy, null); }); it('should save location to server', function () { const expectedData: any = [{ id: 1, name: 'A' }, { id: 2, name: 'B' }]; httpClientSpy.post.and.returnValue(asyncData(expectedData)); findLocalsService.saveLocation('something').subscribe( data => expect(data).toEqual(expectedData), fail ); expect(httpClientSpy.post.calls.count()).toBe(1, 'one call'); });
Here is the service itself
@Injectable() export class FindLocalsService { constructor(private http: HttpClient, private authService: AuthenticationService){} saveLocation(locationObj){ return this.http.post(url + '/findLocals/saveLocation', locationObj); } getThreeClosestPlayers() { const userId = this.authService.currentUser().user._id; console.log('entered 3 closest service', userId); return this.http.get(url + '/findLocals/getThreeClosestPlayers/' + userId) .pipe( map((data: any) => data.obj), catchError(this.handleError) ) } }
fixture is a wrapper for our component's environment so we can control things like change detection. To trigger change detection we call the function fixture.detectChanges() , now we can update our test spec to: Copy it('login button hidden when the user is authenticated', () => { expect(el. nativeElement.
Test the Component logic using SpyOn. SpyOn is a Jasmine feature that allows dynamically intercepting the calls to a function and change its result. This example shows how spyOn works, even if we are still mocking up our service.
fakeAsynclinkWraps a function to be executed in the fakeAsync zone: Microtasks are manually executed by calling flushMicrotasks() . Timers are synchronous; tick() simulates the asynchronous passage of time.
waitForAsynclinkWraps a test function in an asynchronous test zone. The test will automatically complete when all asynchronous calls within this zone are done. Can be used to wrap an inject call.
Change this line:
httpClientSpy.get.and.returnValue(asyncData(expectedHeroes));
to use the Observable operator of()
httpClientSpy.get.and.returnValue(of(expectedHeroes));
This will return an observable that can be subscribed to and will return expectedHeroes. If you are using Angular 6, you can import this directly from rxjs:
import {of} from 'rxjs';
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With