angularunit-testingjasminekarma-jasmine

spyOn isDevMode() in Angular 6+ Unit Tests?


My code includes an if block like this

Service:

import { isDevMode } from '@angular/core';

export class MyService {
  constructor() {}

  methodToTest(): {
    if (!isDevMode()) {
      doSomething();
    } else {
      doSomethingDifferentInDevMode();
    }
  }
}

my-service.spec.ts (the relevant lines only):

it('should run doSomething() when isDevMode() returns false', () => {
  // what should i do here to mock a false value return for isDevMode() ?
  expect(doSomething).toHaveBeenCalled();
});

How do i spyOn the isDevMode() to make it return false for this single Angular unit test so that i may test that doSomething() is called?


Solution

  • Start by wrapping this function into a service:

    import { isDevMode, Injectable } from '@angular/core';
    
    @Injectable({ providedIn: 'root' })
    export class DevModeService {
      constructor() {}
    
      isDevMode() {
        return isDevMode();
      }
    }
    

    Then you can inject this service wherever you want, as you would do with any other service:

    import { DevModeService } from 'dev-mode.service';
    
    export class MyService {
      constructor(private devModeService: DevModeService) {}
    
      methodToTest(): {
        if (!this.devModeService.isDevMode()) {
          doSomething();
        } else {
          doSomethingElse();
        }
      }
    }
    

    And you can then spy on the DevModeService when testing MyService, like you would do with any other dependency:

    it('should do something when in dev mode') {
      const devModeService = TestBed.inject(DevModeService);
      spyOn(devModeService, 'isDevMode').and.returnValue(true);
    
      const myService = TestBed.inject(MyService);
      myService.methodToTest();
      // ...
    }
    
    it('should do something else when in prod mode') {
      const devModeService = TestBed.inject(DevModeService);
      spyOn(devModeService, 'isDevMode').and.returnValue(false);
    
      const myService = TestBed.inject(MyService);
      myService.methodToTest();
      // ...
    }