如何在单元测试中模拟环境文件导入

Bla*_*axy 11 jasmine angular

在我们的角度应用程序中,我们使用环境文件来加载一些配置.

environment.ts

export const environment = {
  production: false,
  defaultLocale: 'en_US',
};
Run Code Online (Sandbox Code Playgroud)

然后我们在我们的服务中使用它:

import { environment } from '../../environments/environment';
import { TranslateService } from './translate.service';

@Injectable()
export class LocaleService {
  constructor(private translateService: TranslateService){}

  useDefaultLocaleAsLang(): void {
    const defaultLocale = environment.defaultLocale;
    this.translateService.setUsedLang(defaultLocale);
  }
}
Run Code Online (Sandbox Code Playgroud)

所以我在服务方法中使用环境文件中的值.

在我们的测试文件中,我们当然可以在translateService上使用Spy:

translateService = jasmine.createSpyObj('translateService', ['setUsedLang']);

但我不知道如何在我的测试文件中模拟环境值(beforeEach例如).或者甚至将它转换为测试目的,Subject以便我可以改变它并测试不同的行为.

更一般地说,如何在测试中模拟这些导入值以确保不使用实际值?

sea*_*ght 9

您无法测试/模拟environment.ts。它不是Angular DI系统的一部分,它是对文件系统上文件的硬性依赖。Angular的编译过程使environment.*.ts您在进行构建时可以在后台交换出不同的文件。

Angular的DI系统是一种典型的面向对象的方法,可以使应用程序的各个部分更易于测试和配置。

我的建议是充分利用DI系统,并尽量使用类似的方法

import { environment } from '../../environments/environment';
Run Code Online (Sandbox Code Playgroud)

而是做Angular为这些依赖所做的事情,它希望您从中抽象出来。提供一项服务,在environment.ts数据和您的应用程序之间提供一个接缝。

它不需要任何逻辑,它可以直接通过environment直接的属性(因此不需要对其自身进行测试)。

然后,在依赖environment.ts于运行时的服务/组件中,您可以使用该服务,而在测试时,您可以对其进行模拟,从其他地方获取数据environment.ts


Cle*_*ent 9

我在这种情况下使用的技术是创建一个包装服务,例如EnvironmentService.ts,在这种情况下它返回环境配置。

这允许我像任何其他调用一样模拟对EnvironmentService's方法的调用。getEnvironmentConfigurationspyOn

这样就可以在单元测试中修改环境变量:)


Mao*_*Mao 7

通过 jest,您可以使用它来模拟您的角度环境:

import { environment } from 'path/to/environments/environment';
jest.mock('path/to/environments/environment', () => ({
  environment: {
    production: false,
    defaultLocale: 'en_US',
  },
}));
Run Code Online (Sandbox Code Playgroud)


R. *_*ter 5

这样的事情对我有用:

it('should ...', () => {
  environment.defaultLocale = <location-to-test>; // e.g. 'en'

  const result = service.method();

  expect(result).toEqual(<expected-result>);
});
Run Code Online (Sandbox Code Playgroud)

  • 我认为这种方法的问题在于它改变了全局变量,因此它可能与需要不同值才能工作的其他测试发生冲突 (3认同)
  • @AlejandroBarone 好点。也许可以选择将environment.defaultLocale重置回afterEach中的原始值。 (2认同)