简体   繁体   English

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

[英]How to mock the window navigator object while unit testing angular code

I am using jasmine to write a unit test in angular.我正在使用 jasmine 以 angular 编写单元测试。 The method uses the the window.navigator property.该方法使用 window.navigator 属性。 The property is defined outside the method like below该属性在方法之外定义,如下所示

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

In the method to be tested the below code is present which is to be tested在要测试的方法中,存在以下要测试的代码

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

The first condition navigator.language gets covered automatically while running the unit test.运行单元测试时,第一个条件navigator.language会自动覆盖。 I want to cover all branches of this code ie, I want to cover all OR conditions while testing.我想覆盖此代码的所有分支,即,我想在测试时覆盖所有 OR 条件。 How do I mock the navigator in unit test?如何在单元测试中模拟导航器?

I created a method to return the navigator instead of refering it directly and then mocked the same method in the spec file.我创建了一个方法来返回导航器,而不是直接引用它,然后在规范文件中模拟了相同的方法。

In the component.ts file-在 component.ts 文件中-

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

In the spec file -在规范文件中 -

Object.defineProperty(navigator, 'userLanguage', {
      get: function () { return 'en'; }
});

I created a custom InjectionToken for it, which can easily be passed in via constructor in Service-tests:我为它创建了一个自定义的 InjectionToken,它可以很容易地通过 Service-tests 中的构造函数传入:


app/tokens/navigator.injection-token.ts : app/tokens/navigator.injection-token.ts

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

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

app/app.module.ts :应用程序/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 :应用程序/服务/语言服务.ts

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

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

Test:测试:

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

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 "Angular 2:如何在单元测试时模拟 ChangeDetectorRef" - Angular 2: How to mock ChangeDetectorRef while unit testing 单元测试:如何使用 Angular + Jasmine 模拟窗口对象的 innerWidth 属性? - Unit testing: How do I mock the innerWidth property on the window object with Angular + Jasmine? 如何使用 object 模拟数组数据以在 Angular 8 中进行单元测试 - How to mock array data with object for unit testing in Angular 8 如何模拟数组中对象的更新:单元测试Angular - How can I mock an update of an object in an array : Unit testing Angular Converting json object to typescript interface causing error in the mock object while unit testing in Angular 11 - Converting json object to typescript interface causing error in the mock object while unit testing in Angular 11 如何在 Angular 单元测试中模拟服务? - How to mock a service in Angular unit testing? 如何在单元测试之外模拟 Angular 服务? - How to mock Angular service outside unit testing? 单元测试时如何模拟 Angular BehaviourSubject - How to mock Angular BehaviourSubject when Unit Testing 如何在 angular 中模拟 rxjs/Websocket 以进行单元测试 - How to mock rxjs/Websocket in angular for Unit Testing 如何为单元测试创建模拟 object - How to create mock object for unit testing
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM