Injecting mock providers only for dev mode


#1

Hello.

I’ve created a couple of mock classes for testing in the browser. When testing on a device, I manually remove these from the providers list before the build. I now want to automatically include or remove them based on the --prod flag.

I have tried various methods, from webpack config, to environment variables, to custom services. In other parts of the app, I use isDevMode() as a quick getter to change some variables. The trouble is that isDevMode() can’t be called before enableProdMode() which appears to be after the main module is set up.

I would like to conditionally add an array of mock providers to the provider list such as:

const mockProviders = [
    { provide: Camera, useClass: CameraMock },
    { provide: Geolocation, useClass: LocationMock },
];

@NgModule({
    providers: [
    	commonProviders,
    	isDevMode() ? mockProviders : []
    ],
    ....

Is there a simple way to do this?

Cheers


#2

I’ve been racking my brain for days to do this cleanly. Tried loads of different examples, and I’ve just managed to solve this, so I’ll post my solution here:

I followed the guide here to set environment variables: https://github.com/gshigeto/ionic-environment-variables

I modified the ENV to have a isDevMode:

export const ENV = {
	mode: 'Production',
	isDevMode: false
}

Before declaring the app module:

import { ENV } from '@app/env';
let isDev = ENV.isDevMode;

And in my providers:

providers: [
		commonProviders,
    	isDev ? mockProviders : []
	]

Hope that can help others!


#3
export interface EnvInterface {

  production: boolean;

  firebase: {
    apiKey: string,
    authDomain: string,
    databaseURL: string,
    projectId: string,
    storageBucket: string,
    messagingSenderId: string
  };

}

export const ENV: EnvInterface = {

  production: false,

  firebase: {
    ...
  }

};

import { ENV } from '@env';

@NgModule({
  imports: [
    CommonModule,
    HttpClientModule,
    IonicModule,
    AngularFireModule.initializeApp(ENV.firebase),
    AngularFirestoreModule,
    AngularFireAuthModule,
    LocalStorageModule,
    // ENV.production ? ServiceWorkerModule.register('/ngsw-worker.js') : []
    ServiceWorkerModule.register('/ngsw-worker.js', { enabled: ENV.production }),
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: HttpLoaderFactory,
        deps: [ HttpClient ]
      }
    })
  ],
  exports: [],
  declarations: [],
  providers: [
    AuthService,
    ENV.production ? { provide: ErrorHandler, useClass: BrewErrorHandler } :
      { provide: ErrorHandler, useClass: IonicErrorHandler},
    { provide: LoggerService, useClass: ConsoleLoggerService },
    ...
  ]
})
export class CoreModule {
  constructor( @Optional() @SkipSelf() parentModule: CoreModule,
               private translate: TranslateService,
               private afs: AngularFirestore) {

    throwIfAlreadyLoaded(parentModule, 'CoreModule');

    translate.setDefaultLang('en');

    const settings = { timestampsInSnapshots: true };
    afs.app.firestore().settings(settings);
  }
}


#4

https://blog.ionicframework.com/ionic-native-mocks/