如何在测试angular 2应用程序时正确使用SharedModules和Router?

时间:2017-09-20 10:19:59

标签: angular unit-testing typescript karma-jasmine

我尝试使用routerLinkrouterLinkActive对(角度2)组件进行单元测试,但所有测试用例都失败并显示以下错误消息。 (注意:我已经删除了路由器和其他相关的依赖项。这里是我用过的reference。)。

  

无法阅读财产'订阅'未定义的

我还注意到,当从我的模板中删除routerLinkrouterLinkActive时,所有测试用例都会正常运行。

我认为错误是由RouterTestingModuleSharedModule (包含用于显示和验证密码输入字段的组件)引起的。所以我尝试删除或添加它们以找到实际导致问题的原因。这是我观察到的。

  • 我得到Cannot read property 'subscribe' of undefined' if RouterTestingModuleSharedModule已存在。
  • 仅当我删除RouterTestingModuleSharedModules时才会收到与路由器关联的任何错误,但SharedModules中的元素不会加载到组件中,而某些测试用例仍然因此而失败。

TestBed配置:

TestBed.configureTestingModule({

            imports: [CoreModule,SharedModule,RouterTestingModule],
            declarations: [ MyComponent,RouterLinkStubDirective,RouterOutletStubComponent ],
            providers: [
                FormBuilder,
                { provide: Router, useClass: RouterStub },
                { provide: ActivatedRoute, userClass: ActivatedRouteStub}
            ],
            schemas: [NO_ERRORS_SCHEMA]
        })
            .overrideComponent(MyComponent, {
                set: {
                    providers: [
                        {provide: AuthModel, useClass: MockAuthModel}    
                    ],
                }
            })
            .compileComponents();
    }));

ActivatedRouterStub:

@Injectable()
export class ActivatedRouteStub {

    // ActivatedRoute.params is Observable
    private subject = new BehaviorSubject(this.testParams);
    params = this.subject.asObservable();

    // Test parameters
    private _testParams: {};
    get testParams() { return this._testParams; }
    set testParams(params: {}) {
        this._testParams = params;
        this.subject.next(params);
    }

    // ActivatedRoute.snapshot.params
    get snapshot() {
        return { params: this.testParams };
    }
}

我应该做些什么改变来解决这个问题?

2 个答案:

答案 0 :(得分:4)

我设法解决了这个问题。我将列出我为解决问题所做的更改。

  1. 正如我在评论中提到的,routerLink仅适用于真实路由器。因此,如果您打算在测试时点击它,我们需要包含 RouterTestingModule (包括.withRoutes([{path: 'some/path',component: someComponent}])。)

  2. 如果我们已添加RouterTestingModule,我们无需单独提供路由器依赖项。所以我删除了我提供的RouterActivatedRoute依赖项。现在,错误已从Cannot read property 'subscribe' of undefined更改为Cannot read property 'outlets' of null

  3. routerLink 指向空变量时,我found出现此错误。在我的例子中,由于隔离的测试环境,我分配给favoriteUrl的名为routerLink的属性为null。所以我手动为beforeEach函数中的属性赋值,这解决了问题,至少对我而言。

  4. 感谢所有试图提供帮助的人! : - )

    的参考文献:

    https://stackoverflow.com/a/45916133/8558515

    https://stackoverflow.com/a/42039920/8558515

答案 1 :(得分:0)

Angular无法知道您希望它使用您自己创建的activatedRoute变量(根据注释),因此它将创建默认变量并在DI中使用它。使用{ provide: ActivatedRoute, useValue: mockInstance}而不是ActivatedRoute依赖项的当前设置,其中mockInstanceActivatedRoute的模拟,您可以使用jasmine.createSpyObj

创建