在我们的角度应用程序中,我们使用环境文件来加载一些配置。
environment.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上使用Spy:
translateService = jasmine.createSpyObj('translateService', ['setUsedLang']);
但我不知道如何在我的测试文件中模拟环境值(例如在beforeEach
中)。或者甚至将其转换为Subject
以进行测试,以便我可以更改它并测试不同的行为。
更一般地说,如何在测试中模拟这些导入值以确保不使用实际值?
答案 0 :(得分:4)
您无法测试/模拟environment.ts
。它不是Angular DI系统的一部分,它是对文件系统上文件的硬性依赖。 Angular的编译过程使您可以在进行构建时替换掉不同的environment.*.ts
文件。
Angular的DI系统是一种典型的面向对象的方法,可以使应用程序的各个部分更易于测试和配置。
我的建议是充分利用DI系统并尽量使用类似的方法
import { environment } from '../../environments/environment';
代替Angular为这些依赖所做的事情,它希望您从中抽象出来。进行一项服务,在environment.ts
数据和您的应用程序段之间提供一个接缝。
它不需要任何逻辑,它可以直接直接通过environment
的属性(因此它本身不需要测试)。
然后在运行时依赖environment.ts
的服务/组件中可以使用该服务,并且在测试时可以对其进行模拟,从environment.ts
以外的其他地方获取数据
答案 1 :(得分:1)
类似的事情对我有用:
it('should test', () => {
environment.defaultLocale = <location-to-test>;
const result = service.method();
expect(result).toEqual(<expected-result>);
});
答案 2 :(得分:0)
我在这种情况下使用的一种技术是创建包装器服务,例如EnvironmentService.ts
,在这种情况下,它将返回环境配置。
这使我可以像其他任何EnvironmentService
调用一样模拟对getEnvironmentConfiguration
的{{1}}方法的调用。
然后可以在单元测试中修改环境变量:)