Last active
July 21, 2017 19:36
-
-
Save kkoziarski/a5a2b91828604aee265f4e3abd966032 to your computer and use it in GitHub Desktop.
Angular testing services - implementation of https://angular.io/guide/testing#services and https://github.com/angular/angular/tree/master/aio/content/examples/testing/src/app/bag
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Injectable } from "@angular/core"; | |
import { TestBed, async, inject } from '@angular/core/testing'; | |
import { HttpModule, Http, Response, ResponseOptions, XHRBackend } from '@angular/http'; | |
import { MockBackend } from '@angular/http/testing'; | |
import { Observable } from 'rxjs/Rx'; | |
@Injectable() | |
export class FancyService { | |
protected value = 'real value'; | |
getValue() { return this.value; } | |
setValue(value: string) { this.value = value; } | |
getAsyncValue() { return Promise.resolve('async value'); } | |
getObservableValue() { return Observable.of('observable value'); } | |
getTimeoutValue() { | |
return new Promise((resolve) => { | |
setTimeout(() => { resolve('timeout value'); }, 10); | |
}); | |
} | |
getObservableDelayValue() { | |
return Observable.of('observable delay value').delay(10); | |
} | |
} | |
@Injectable() | |
export class FancyHttpService extends FancyService { | |
public actionUrl: string; | |
constructor(private _http: Http = null) { | |
super(); | |
this.actionUrl = 'http://example.com/api/values/'; | |
} | |
public getHttpValue = (): Observable<Response> => { | |
return this._http | |
.get(this.actionUrl + 123); | |
} | |
} | |
@Injectable() | |
export class DependentService { | |
constructor(private dependentService: FancyHttpService) { } | |
getValue() { return this.dependentService.getValue(); } | |
getHttpValue() { return this.dependentService.getHttpValue(); } | |
} | |
export class FakeFancyService extends FancyService { | |
value = 'faked value'; | |
} | |
export class FakeFancyHttpService extends FancyHttpService { | |
value = 'faked http value'; | |
} | |
///////////////////////////////////////////////////////////////// | |
// Straight Jasmine - no imports from Angular test libraries | |
describe('Straight Jasmine - no imports from Angular test libraries - FancyService without the TestBed', () => { | |
let service: FancyService; | |
beforeEach(() => { service = new FancyService(); }); | |
it('#getValue should return real value', () => { | |
expect(service.getValue()).toBe('real value'); | |
}); | |
it('#getAsyncValue should return async value', (done: DoneFn) => { | |
service.getAsyncValue().then(value => { | |
expect(value).toBe('async value'); | |
done(); | |
}); | |
}); | |
it('#getTimeoutValue should return timeout value', (done: DoneFn) => { | |
service = new FancyService(); | |
service.getTimeoutValue().then(value => { | |
expect(value).toBe('timeout value'); | |
done(); | |
}); | |
}); | |
it('#getObservableValue should return observable value', (done: DoneFn) => { | |
service.getObservableValue().subscribe(value => { | |
expect(value).toBe('observable value'); | |
done(); | |
}); | |
}); | |
}); | |
///////////////////////////////////////////////////////////////// | |
describe('FancyService with the TestBed', () => { | |
beforeEach(() => { | |
TestBed.configureTestingModule({ providers: [FancyService] }); | |
}); | |
it('test should wait for FancyService.getTimeoutValue', | |
async(inject([FancyService], (service: FancyService) => { | |
service.getTimeoutValue().then( | |
value => expect(value).toBe('timeout value') | |
); | |
}))); | |
}); | |
///////////////////////////////////////////////////////////////// | |
describe('DependentService without the TestBed', () => { | |
let service: DependentService; | |
it('#getValue should return real value by way of the real FancyService', () => { | |
service = new DependentService(new FancyHttpService()); | |
expect(service.getValue()).toBe('real value'); | |
}); | |
it('#getValue should return faked value by way of a fakeService', () => { | |
service = new DependentService(new FakeFancyHttpService()); | |
expect(service.getValue()).toBe('faked http value'); | |
}); | |
it('#getValue should return faked value from a fake object', () => { | |
const fake = { getValue: () => 'fake value' }; | |
service = new DependentService(fake as FancyHttpService); | |
expect(service.getValue()).toBe('fake value'); | |
}); | |
it('#getValue should return stubbed value from a FancyService spy', () => { | |
const fancy = new FancyHttpService(); | |
const stubValue = 'stub value'; | |
const spy = spyOn(fancy, 'getValue').and.returnValue(stubValue); | |
service = new DependentService(fancy); | |
expect(service.getValue()).toBe(stubValue, 'service returned stub value'); | |
expect(spy.calls.count()).toBe(1, 'stubbed method was called once'); | |
expect(spy.calls.mostRecent().returnValue).toBe(stubValue); | |
}); | |
}); | |
///////////////////////////////////////////////////////////////// | |
describe('DependentService with the TestBed', () => { | |
let service: DependentService; | |
beforeEach(() => { | |
TestBed.configureTestingModule({ | |
imports: [HttpModule], | |
providers: [ | |
{ provide: XHRBackend, useClass: MockBackend }, | |
{ provide: FancyHttpService, useClass: FakeFancyHttpService }, | |
DependentService | |
] | |
}); | |
}); | |
it('#getValue should return faked value by way of a fakeService', | |
async(inject([DependentService], (service: DependentService) => { | |
expect(service.getValue()).toBe('faked http value'); | |
}))); | |
it('#getValue should return stubbed value from a FancyService spy', | |
async(inject([DependentService, FancyHttpService], (service: DependentService, fancy: FancyHttpService) => { | |
const stubValue = 'stub value'; | |
const spy = spyOn(fancy, 'getValue').and.returnValue(stubValue); | |
expect(service.getValue()).toBe(stubValue, 'service returned stub value'); | |
expect(spy.calls.count()).toBe(1, 'stubbed method was called once'); | |
expect(spy.calls.mostRecent().returnValue).toBe(stubValue); | |
}))); | |
it('#getHttpValue should return stubbed value from a MockResponse service', | |
async(inject([DependentService, XHRBackend], (service: DependentService, mockBackend) => { | |
const mockResponse = 'Value 0'; | |
mockBackend.connections.subscribe((connection) => { | |
connection.mockRespond(new Response(new ResponseOptions({ | |
body: JSON.stringify(mockResponse) | |
}))); | |
}); | |
service.getHttpValue().subscribe((response) => { | |
let responseBody = response.json(); | |
expect(responseBody).toEqual('Value 0'); | |
}); | |
}))); | |
it('#getHttpValue should return stubbed value from a FancyService spy', | |
async(inject([DependentService, FancyHttpService], (service: DependentService, fancy: FancyHttpService) => { | |
const stubValue = 'stub value 0'; | |
const response = new Response(new ResponseOptions({ | |
body: JSON.stringify(stubValue) | |
})); | |
const spy = spyOn(fancy, 'getHttpValue').and.returnValue(Observable.of(response)); | |
let result = service.getHttpValue().subscribe((response) => { | |
let responseBody = response.json(); | |
expect(responseBody).toEqual(stubValue); | |
}); | |
expect(spy.calls.count()).toBe(1, 'stubbed method was called once'); | |
}))); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment