在单元测试角度代码时如何模拟窗口导航器对象

时间:2019-02-06 16:25:42

标签: angular unit-testing

我正在用茉莉花编写成角度的单元测试。该方法使用window.navigator属性。该属性是在方法外部定义的,如下所示

declare var navigator: any;
navigator = window.navigator;

在要测试的方法中,存在以下要测试的代码

let locale = navigator.language || navigator.userLanguage || navigator.browserLanguage; 

运行单元测试时,第一个条件navigator.language被自动覆盖。 我想覆盖此代码的所有分支,即,我想覆盖测试时的所有OR条件。如何在单元测试中模拟导航器?

2 个答案:

答案 0 :(得分:1)

我为此创建了一个自定义的InjectionToken,可以轻松地通过构造函数在Service-tests中将其传递:


app / tokens / navigator.injection-token.ts

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

export const NavigatorToken = new InjectionToken('navigator-token');

app / app.module.ts

import { NavigatorToken } from './tokens/navigator.injection-token.ts';

@NgModule({
  providers: [
    {
      provide: NavigatorToken,
      useValue: navigator,
    }
  ]
})
export class AppModule {}

app / services / language-service.ts

export class MyService {
  constructor(@Inject(NavigatorToken) private navigatorInstance: typeof navigator) {}

  get browserLanguage(): string {
    return this.navigatorInstance.language;
  }
}

测试:

describe('MyService', () => {
  let service: MyService;

  beforeEach(() => {
    service = new MyService({ language: 'mock-lang' } as any);
  });

  it('should work', () => {
    expect(service.browserLanguage).toBe('mock-lang');
  });
});

答案 1 :(得分:0)

我创建了一个方法来返回导航器,而不是直接引用它,然后在spec文件中模拟了相同的方法。

在component.ts文件中-

var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.moveTo(canvas.prevX, canvas.prevY);
ctx.lineTo(newPoint.x, newPoint.y);
ctx.stroke();
ctx.closePath();
canvas.prevX = newPoint.x;
canvas.prevY = newPoint.y;
canvas.requestPaint();

在规格文件中-

// method that returns navigator object
public getNavigatorReference(): any {
    return navigator;
}

// method that uses the above method
private methodThatUsesNavigator(): void {
   let navigatorReference = this.getNavigatorReference();
   let locale = navigatorReference.language || navigatorReference.userLanguage || 
   navigatorReference.browserLanguage;
...
}