設置:加載配置數據的APP_INITIALIZER服務ConfigurationService
正在整個應用程序組件和服務中使用。當單元測試組件時,它會讀取配置文件並正確評估。當使用配置的單元測試服務失敗時。Angular2/Jasmine:以另一個服務作爲依賴性的測試服務
它設置如下:
app.module.ts
export function ConfigurationFactory(config: ConfigurationService): any {
// this line actually triggers the loading of the config file
return() => config.load();
}
@NgModule({
bootrstrap: {},
...,
providers : [
ConfigurationService,
{
deps: [ ConfigurationService ],
multi: true,
provide: APP_INITIALIZER,
useFactory: ConfigurationFactory,
}
]
})
ConfigurationService.ts
@Injectable()
export class ConfigurationService {
// error holder
public error: boolean = false;
// data holder
public data: any = {};
// config file url
private configUrl: string = './assets/config/config.json';
constructor(private http: Http) {
}
/**
* reads config file
*/
public load(): Promise<any> {
return this.http.get(this.configUrl)
.map((response: any) => response.json())
.toPromise()
.then((data: any) => this.data = data)
.catch((err: any) => Promise.resolve());
}
}
這裏是TestableService.service.ts使用配置服務的也是
@Injectable()
export class TestableService extends SomeAbstractHttpService {
constructor(http: Http,
private config: ConfigurationService) {
super(http);
}
public setRequest(sessionId: string, isIdent: boolean): void {
if (isIdent) {
this.resourceUrl = `${ this.config.data.contextRootRest}/documents/ident/${sessionId}`;
} else {
this.resourceUrl = `${ this.config.data.contextRootRest}/documents/noident/${sessionId}`;
}
this.headers = new Headers();
this.headers.append('Content-Type', 'application/json');
this.headers.append('Accept', 'application/json, application/pdf');
this.requestOptions = new RequestOptions({
headers: this.headers,
responseType: ResponseContentType.Blob
});
}
}
我們spec文件,TestableService.service.spec.ts
export function ConfigurationFactory(config: ConfigurationService): any {
return() => config.load();
}
describe('TestableService',() => {
// not ideal to hardcode it here, I would prefer using the same config file, which is used across the app!
let mockConfig: any = {contextRootRest: 'rest/'};
let theService: TestableService;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
HttpModule,
],
providers: [
TestableService,
MockDataService,
{ provide: XHRBackend, useClass: MockBackend },
ConfigurationService,
{
// Provider for APP_INITIALIZER
deps: [ ConfigurationService ],
multi: true,
provide: APP_INITIALIZER,
useFactory: ConfigurationFactory,
},
]
});
}));
// I suspect, that using APP_INITIALIZER at this stage is goofy,
// as I do not in fact instantiate the app, only the service.
// What would be the correct way to do it here?
beforeEach(inject([ TestableService, XHRBackend ], (service: TestableService, backend: MockBackend) => {
theService = service;
mockBackend = backend;
}));
it('should set request correctly', () => {
theService.setRequest('1234567890', true);
expect(theService.resourceUrl)
.toEqual(`${ mockConfig.contextRootRest }/documents/ident/1234567890`);
});
});
它失敗Expected 'undefined/documents/ident/1234567890' to equal 'rest/documents/ident/1234567890'
- 這意味着,配置服務尚未在TestableService加載在所有。有任何想法嗎?