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

San*_*nju 6 unit-testing typescript karma-jasmine angular

我正在尝试对(角度2)组件进行单元测试routerLink,routerLinkActive但是所有测试用例都会失败,并显示以下错误消息.(注意:我已经删除了路由器和其他相关的依赖项.这是我用于相同的参考.).

无法读取undefined的属性'subscribe'

我也注意到,当routerLinkrouterLinkActive从我的模板被删除,所有测试用例将没有任何错误运行.

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

  • 我得到' Cannot read property 'subscribe' of undefined'如果 RouterTestingModuleSharedModule现在.
  • 我没有得到任何链接到路由器的错误,只有当我删除两个RouterTestingModule,SharedModules但是组件中的元素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();
    }));
Run Code Online (Sandbox Code Playgroud)

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 };
    }
}
Run Code Online (Sandbox Code Playgroud)

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

San*_*nju 4

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

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

  2. 如果我们已经添加了 Router 依赖项,则无需单独提供RouterTestingModule。所以我删除了我提供的两者Router和依赖项。ActivatedRoute现在,错误从Cannot read property 'subscribe' of undefined变为Cannot read property 'outlets' of null

  3. 发现当routerLink 指向空变量时会发生此错误。就我而言,由于隔离的测试环境,favoriteUrl我分配给的属性调用为空。routerLink因此,我手动为函数中的属性分配了一个值beforeEach,这解决了问题,至少对我来说是这样。

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

参考:

/sf/answers/3214129341/

/sf/answers/2942794431/