我正在Angular应用程序中进行单元测试,我正在使用TestBed方法,
我正在测试组件,所以每个spec文件都是这样的
import...
describe('AppComponent', () => {
// Importing dependecies
beforeEach(async(() => {
TestBed.configureTestingModule({
imports : [RouterTestingModule , HttpModule , FormsModule ],
declarations: [AppComponent
],
providers: [AUTH_PROVIDERS ,UserService, SharedclientService, RouteNavigator, JwtHelper, ReloadTokenService, ShopService
, EnvVarsService, ProfileService, LocalStorageService, ApiVersionInterceptor, ApiTrackingInterceptor, MonitoringService ,
{ provide: 'LOCAL_STORAGE_SERVICE_CONFIG', useValue: userConfig } , TokenUtilService , HttpInterceptorService ,
{ provide: InterceptableStoreFactory, useClass: InterceptableStoreFactoryMock },ReloadTokenEventService , InterceptableStoreFactory
]
}).compileComponents();
}));
// detecting changes every times
beforeEach(() => {
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
// Test case 0 (compilation of the component)
it('AppComponent is well defined', () => {
expect(component).toBeDefined();
});
// Test case 1
it('test', () => {
expect("1").toBe("1");
});
});
如果依赖项导入不好,这种测试方法会导致整个测试套件失败 .
For example :在此测试套件中,它会抛出此错误:
没有InterceptableStoreFactory的提供商!这似乎很奇怪,因为我在我的供应商中导入此服务(最后一个)
这导致几乎所有测试用例的失败,因为夹具导入的验证是“beforeEach”测试用例
Am looking for 更好的想法:
- "no provider for service"的问题(已经添加到提供者“
并为
- 单元testBed更好的测试方法
2 回答
您提供两次InterceptableStoreFactory . 一次用模拟替换,一次用原版 . 尝试删除其中一个 .
它可以帮助您为所有服务创建一个模块并将其放在'core'文件夹中 . (见Angular Style Guide)
这样可以更轻松地在测试和开发/ 生产环境 中提供所有正确的服务,而无需如此重复 .
1. No provider for service
删除providers数组中的尾随
InterceptableStoreFactory
. 因为您之前已经在同一行注入了模拟服务InterceptableStoreFactory
.如果这不能修复它,请提供您的模拟类
InterceptableStoreFactoryMock
和InterceptableStoreFactory
的片段 .2. Better Test Strategy
为了更好的测试策略,我建议一些使测试更容易的事情:
在Angular Styleguide中
建议here:将所有全局服务收集到一个
CoreModule
中 . 然后,您可以轻松地知道所有服务都已导入并轻松导入它们以进行测试 . 如果你想以相同的方式为许多组件模拟许多服务,我还会建议创建一个明确的CoreTestingModule
. 从而保留了所有测试的可重用性 .建议here在Angular Styleguide中:
SharedModule
,您可以在其中导出在应用程序中重复使用的组件,指令和管道 .考虑使用非常小的模块 . 在2017年下半年或2018年初的一次 Session 的常见问题解答中,Rob Wormald提到Google Angular项目中的每个模块平均只有1.6个组件 . 这意味着组件的每个测试都不太可能包含它实际上不需要的服务和其他导入 . 因此,如果更改了很多组件使用的大模块,也需要更少的重构测试 . 对于较小的模块,
TestBed
也会快得多,因为在每个测试用例之后重新初始化_1184506会快得多 .考虑将大多数逻辑转移到服务和管道,并主要将测试焦点转移到它们 . 由于测试服务和管道可以使用常规测试基础架构,因此可以避免创建模块的复杂性,因为服务和管道可以像常规类和函数一样对待 . 作为附注,我提到通过迁移到NGRX architecture或多或少会自动完成 .
This issue正在跟踪
TestBed
的更大性能改进 . 现在的问题是你必须在每个测试用例之间重新创建和拆除模块 . 使它比测试服务,管道和其他纯函数和类慢得多 . 如前所述,通过使用较小的模块可以解决这个问题 . 该问题还显示了一些使用Jest或变通方法的黑客攻击,因此不需要为每个测试用例重新创建模块,而是可以重复使用 . 然而,后者会更改私有API,因此很容易在Angular的补丁版本之间破坏您的应用程序,这不是一个好地方 .