简体   繁体   中英

Angular 2+ - How to mockup constant class used for environment variables

I was wondering if someone could help me on this topic, I'm typing down some unit tests regarding to some functionalities that are done depending on the environment that's running at the moment.

This is my source code of the component I want to create the unit 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);
  }

And and this is the unit testing:

 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.supportedLanguages);

        component.ngOnInit();

        expect(spy_enableProductionModeLoggerMethod).toHaveBeenCalledBefore(spy_debugLoggerAttr);
        expect(spy_debugLoggerAttr).toHaveBeenCalledBefore(spy_initI8nServiceMethod);
        expect(spy_initI8nServiceMethod).toHaveBeenCalledWith(environmentPRO.environment.defaultLanguage,
                                                              environmentPRO.environment.supportedLanguages);
       }));
 });

My problem is that I'm unable to force constant environment to return certain values, I've both tried both spyOn & spyOnAttribute with same result. What's wrong here? shall I try another approach?

I've thought about this and I believe that maybe it could be a security leak to keep a configuration file as typescript (that will be converted into JavaScript in execution time) and it which looks like that, based on @mixth comments, can't be tested anyway so I'll follow your recommendations and I'll use a injectable service instead and json files to store settings. Thanks for the insight and stackoverflow's thread reference @mixth

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM