单元测试:没有" InterceptableStoreFactory"即使添加到"提供商"

时间:2017-10-30 14:25:47

标签: angular unit-testing jasmine fixtures testbed

我正在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");
    });
});

这种测试方法导致整个测试套件失败,如果导入的依赖关系不好。

例如:在此测试套件中,它会抛出此错误:

  

InterceptableStoreFactory 没有提供商!   这似乎很奇怪,因为我在提供商(最后一个)中导入了这项服务

这几乎导致所有测试用例的失败,因为对于夹具进口的验证是" beforeEach "测试用例

我正在寻找更好的想法:

  1. 没有提供服务的问题" (已经添加到提供者"
    1. 单元测试更好的测试方式

2 个答案:

答案 0 :(得分:3)

您提供两次InterceptableStoreFactory。一次用模拟替换,一次用原版。尝试删除其中一个。

它可以帮助您为所有服务创建一个模块并将其放在'core'文件夹中。 (见Angular Style Guide

这样可以更轻松地在测试和开发/生产中提供所有正确的服务,而无需重复太多。

答案 1 :(得分:2)

<强> 1。没有服务提供商

删除providers数组中的尾随InterceptableStoreFactory。因为您之前已经在同一行注入了模拟服务InterceptableStoreFactory

如果不能解决问题,请提供您的模拟课程InterceptableStoreFactoryMockInterceptableStoreFactory的摘要。

<强> 2。更好的测试策略

为了更好的测试策略,我建议一些方法来简化测试:

  1. Angular Styleguide中的建议here:将所有全球​​服务收集到一个CoreModule中。然后,您可以轻松地知道所有服务都已导入并轻松导入它们以进行测试。如果你想以相同的方式为许多组件模拟许多服务,我还会建议创建一个显式的CoreTestingModule。从而保留了所有测试的可重用性。
  2. Angular Styleguide中的建议hereSharedModule,您可以在其中导出在应用中重复使用的组件,指令和管道。
  3. 考虑使用非常小的模块。在2017年下半年或2018年初的一次会议的常见问题解答中,Rob Wormald提到Google Angular项目中的每个模块平均只有1.6个组件。这意味着组件的每个测试都不太可能包含它实际上不需要的服务和其他导入。因此,如果更改了很多组件使用的大模块,也需要更少的重构测试。使用较小的模块,TestBed也会快得多,因为在每个测试用例后重新初始化TestBed的速度要快得多。
  4. 考虑将大多数逻辑转移到服务和管道,并主要将测试焦点转移到它们。由于测试服务和管道可以使用常规测试基础架构,因此可以避免创建模块的复杂性,因为服务和管道可以像常规类和函数一样对待。作为附注,我提到通过迁移到NGRX architecture,这或多或少会自动完成。
  5. This issue正在跟踪TestBed的更大性能提升。现在的问题是你必须在每个测试用例之间重新创建和拆除模块。使它比测试服务,管道和其他纯函数和类慢得多。如前所述,通过使用较小的模块可以解决这个问题。该问题还显示了一些使用Jest或变通方法的黑客攻击,因此不需要为每个测试用例重新创建模块,而是可以重复使用。然而,后者会更改私有API,因此很容易在Angular的补丁版本之间破坏您的应用程序,这不是一个好地方。