Can anyone assist me with writing unit tests for functionalities that depend on the current environment? I am struggling to force a constant environment to return specific values in my source code. Here is the component code I need to test:
import { Component, OnInit } from '@angular/core';
// DEV environment
import { environment } from '@env/environment';
// PROD environment
// import { environment } from '@env/environment.prod';
import { Logger } from '@app/core/logger/logger.service';
import { I18nService } from '@app/core/language/i18n.service';
let log: Logger;
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
providers: [I18nService]
})
export class AppComponent implements OnInit {
constructor(private i18nService: I18nService) {
log = new Logger('X');
}
ngOnInit() {
// Setup logger
if (environment.isProduction) {
Logger.enableProductionMode();
}
log.debug('init');
// Setup translations
this.i18nService.init(environment.defaultLanguage, environment.supportedLanguages);
}
Here is the unit testing code:
import * as environmentDEV from '@env/environment';
import * as environmentPRO from '@env/environment.prod';
...
let component: AppComponent;
let fixture: ComponentFixture<AppComponent>;
// Spies declarations
let spy_initI8nServiceMethod: jasmine.Spy;
let spy_debugLoggerAttr: jasmine.Spy;
let spy_enableProductionModeLoggerMethod: jasmine.Spy;
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot()],
declarations: [AppComponent],
providers: [I18nService]
});
TestBed.compileComponents();
fixture = TestBed.createComponent(AppComponent);
component = fixture.debugElement.componentInstance;
}));
beforeEach(inject([I18nService],
(_i18nService: I18nService) => {
i18nService = _i18nService;
// Create spies
// Spies
spy_initI8nServiceMethod = spyOn(I18nService.prototype, 'init');
spy_debugLoggerAttr = spyOn(Logger.prototype, 'debug');
spy_enableProductionModeLoggerMethod = spyOn(Logger, 'enableProductionMode');
}));
it('should component init on PRO environment',
async(() => {
spyOn(environment, 'isProduction').and.returnValue(environmentPRO.environment.isProduction);
spyOn(environment, 'defaultLanguage').and.returnValue(environmentPRO.environment.defaultLanguage);
spyOn(environment, 'supportedLanguages').and.returnValue(environmentPRO.environment.supp...
component.ngOnInit();
expect(spy_enableProductionModeLoggerMethod).toHaveBeenCalledBefore(spy_debugLoggerAttr);
expect(spy_debugLoggerAttr).toHaveBeenCalledBefore(spy_initI8nServiceMethod);
expect(spy_initI8nServiceMethod).toHaveBeenCalledWith(environmentPRO.environment.defaultLangua...
}));
});
I have tried using spyOn and spyOnAttribute to force the constant environment to return specific values but without success. Can anyone point out what I might be doing wrong here? Should I consider trying a different approach?