【问题标题】:How to mock environment files import in unit tests如何在单元测试中模拟环境文件导入
【发布时间】:2018-08-11 23:35:12
【问题描述】:

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

环境.ts

export const environment = {
  production: false,
  defaultLocale: 'en_US',
};

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

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);
  }
}

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

在我们的测试文件中,我们当然可以监视 translateService:

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

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

更一般地说,您如何在测试中模拟此类导入值以确保不使用真实值?

【问题讨论】:

  • 将环境包装在一个加载它的接口中 (EnvironmentLoader) 并模拟它?
  • 是的,我可以,但是如何测试 EnvironmentLoader 类和方法?问题已解决但未修复。

标签: angular jasmine


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    Angular 的 DI 系统是一种典型的面向对象方法,可让您的应用程序的某些部分更具可测试性和可配置性。

    我的建议是利用 DI 系统并谨慎使用类似的东西

    import { environment } from '../../environments/environment';
    

    相反,Angular 对它希望你从中抽象出来的任何依赖项做同样的事情。创建一个服务,在environment.ts 数据和您的应用程序片段之间提供接缝。

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

    然后更新依赖于environment.ts 的服务/组件,并将该依赖项替换为服务。在测试时你可以模拟它,从environment.ts以外的地方获取数据

    【讨论】:

      【解决方案3】:

      这样的事情对我有用:

      it('should ...', () => {
        environment.defaultLocale = <location-to-test>; // e.g. 'en'
      
        const result = service.method();
      
        expect(result).toEqual(<expected-result>);
      });
      

      【讨论】:

      • 我认为这种方法的问题在于它改变了全局变量,因此它可能会与需要不同值才能工作的其他测试发生冲突
      • @AlejandroBarone 好点。也许将 environment.defaultLocale 重置为 afterEach 中的原始值是一个选项。
      【解决方案4】:

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

      这允许我模拟对EnvironmentServicegetEnvironmentConfiguration 方法的调用,就像任何其他spyOn 调用一样。

      这允许在单元测试中修改环境变量:)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-23
        • 1970-01-01
        • 2022-08-11
        • 2021-12-09
        • 2013-11-09
        相关资源
        最近更新 更多