spyOn isDevMode() 在 Angular 6+ 单元测试中?

问题描述 投票:0回答:3

我的代码包含一个像这样的

if

服务:

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

export class MyService {
  constructor() {}

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

my-service.spec.ts(仅限相关行):

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

我如何监视

isDevMode()
使其对于这个单个 Angular 单元测试返回 false,以便我可以测试
doSomething()
是否被调用?

angular unit-testing jasmine karma-jasmine
3个回答
10
投票

首先将此函数包装到服务中:

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

@Injectable({ providedIn: 'root' })
export class DevModeService {
  constructor() {}

  isDevMode() {
    return isDevMode();
  }
}

然后您可以在任何您想要的地方注入此服务,就像您对任何其他服务所做的那样:

import { DevModeService } from 'dev-mode.service';

export class MyService {
  constructor(private devModeService: DevModeService) {}

  methodToTest(): {
    if (!this.devModeService.isDevMode()) {
      doSomething();
    } else {
      doSomethingElse();
    }
  }
}

然后,您可以在测试 MyService 时监视 DevModeService,就像处理任何其他依赖项一样:

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();
  // ...
}

0
投票

看来答案就在评论里了。谢谢@JBNizet。

// dev-mode-service.ts

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

export class DevModeService {
  constructor() {}

  isDevMode(): {
    return isDevMode();
  }
}


// MyService.ts

import { isDevMode } from 'dev-mode-service';

export class MyService {
  constructor() {}

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

0
投票

我正在使用的方法如下

import { enableProdMode, isDevMode } from '@angular/core';
declare const global: any;

describe('teststing IsDevMode', () => {
    beforeEach(() => {
        /**
         * We must reset the devmode to true before each test, as it is the default non prod state
         *
         */
        global['ngDevMode'] = true;
    });

    it('should be true in tests', () => {
        expect(isDevMode()).toBe(true);
    });
    it('should be false for prod using ngInternals', () => {
        enableProdMode();
        expect(isDevMode()).toBe(false);
    });
    it('should be false for prod', () => {
        global['ngDevMode'] = false;
        expect(isDevMode()).toBe(false);
    });
});

所以基本上我们正在覆盖用于检查项目是否处于 devMode 的全局变量。您可以在这里了解内部结构是如何工作的:AngularGitHub

© www.soinside.com 2019 - 2024. All rights reserved.