I am very new to writing tests in Karma and Jasmine. In my case, I have a dynamic configuration file that loads before the app is initialized and that file is a JSON with a value.
configuration.json
{
"sampleConfigValue": "this is a sample value from config"
}
Configuration.ts
export interface Configuration {
sampleConfigValue: string;
}
ConfigurationService.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Configuration } from './configuration';
@Injectable({
providedIn: 'root'
})
export class ConfigurationService {
private configData: any | undefined;
private readonly configPath: string = '../assets/demo/data/config.json';
constructor(
private http: HttpClient
) { }
async loadConfiguration(): Promise<any> {
try {
const response = await this.http.get(`${this.configPath}`)
.toPromise().then(res => this.configData = res);
return this.configData;
} catch (err) {
return Promise.reject(err);
}
}
get config(): Configuration | undefined {
return this.configData;
}
}
Exporting the ConfigurationLoader in app.module.ts
export function configLoader(injector: Injector) : () => Promise<any>
{
return () => injector.get(ConfigurationService).loadConfiguration();
}
and Provider in app.module.ts
{provide: APP_INITIALIZER, useFactory: configLoader, deps: [Injector], multi: true},
configuration.service.spec.ts
import { TestBed } from '@angular/core/testing';
import { ConfigurationService } from './configuration.service';
describe('ConfigurationService', () => {
let service: ConfigurationService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(ConfigurationService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
The configuration file is working but I am wondering how to write a test case for this dynamic configuration in my project?
Your time and help will really help me :)
Thanks :)
CodePudding user response:
When unit testing, you're supposed to test a code unit and mock the rest.
So create a mock then test :
// Put this in the main describe
const returnValue = {};
let httpMock: { get: jasmine.Spy };
let service: ConfigurationService;
// Put this in the main beforeEach
httpMock = {
get: jasmine.createSpy().and.returnValue(of(returnValue)),
};
service = new ConfigurationService(<any>httpMock);
// Make a meaningful test
it('Should call the endpoint and retrieve the config', (done) => {
service.loadConfiguration().then(() => {
expect(httpMock.get)
.toHaveBeenCalledOnceWith(service['configPath']);
expect(service['configData']).toBe(returnValue);
done();
});
});