清理组件时发生TypeError

问题描述 投票:0回答:1

我试图弄清楚为什么我的角度分量测试失败。从堆栈跟踪看,问题似乎来自_subscriptions对象为undefined的事实,但我不知道这是怎么可能的,或者为什么会如此。那是测试失败时我得到的完整堆栈:

HeadlessChrome 79.0.3945 (Windows 10.0.0): Executed 8 of 26 SUCCESS (0 secs / 0.191 secs)
ERROR: 'Error during cleanup of component', Object{component: PlayerComponent{...}, _subscriptions: Object{routerSubscription: ...}}, stacktrace: TypeError: Cannot read property 'unsubscribe' of undefined
TypeError: Cannot read property 'unsubscribe' of undefined
    at http://localhost:9876/_karma_webpack_/src/app/player/player.component.ts:58:29
    at Array.map (<anonymous>)
    at PlayerComponent.ngOnDestroy (http://localhost:9876/_karma_webpack_/src/app/web-player/web-player.component.ts:57:36)
    at callProviderLifecycles (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:28212:1)
    at callElementProvidersLifecycles (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:28171:1)
    at callLifecycleHooksChildrenFirst (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:28153:1)
    at destroyView (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:38603:1)
    at callWithDebugContext (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:39716:1)
    at Object.debugDestroyView [as destroyView] (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:39313:1)
    at ViewRef_.destroy (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:27128:1)}
HeadlessChrome 79.0.3945 (Windows 10.0.0): Executed 9 of 26 SUCCESS (0 secs / 0.207 secs)
ERROR: 'Error during cleanup of component', Object{component: PlayerComponent{router: Object{navigate: ..., events: ...}, _subscriptions: Object{routerSubscription: ...}}, stacktrace: TypeError: Cannot read property 'unsubscribe' of undefined
TypeError: Cannot read property 'unsubscribe' of undefined
    at http://localhost:9876/_karma_webpack_/src/app/web-player/web-player.component.ts:58:29
    at Array.map (<anonymous>)
    at PlayerComponent.ngOnDestroy (http://localhost:9876/_karma_webpack_/src/app/web-player/web-player.component.ts:57:36)
    at callProviderLifecycles (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:28212:1)
    at callElementProvidersLifecycles (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:28171:1)
    at callLifecycleHooksChildrenFirst (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:28153:1)
    at destroyView (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:38603:1)
    at callWithDebugContext (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:39716:1)
    at Object.debugDestroyView [as destroyView] (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:39313:1)

这是我的PlayerComponent.ts:

import { Component, OnInit, OnDestroy, Input } from '@angular/core';
import { Router, RouterEvent, NavigationStart } from '@angular/router';
import { combineLatest, Subscription } from 'rxjs';

export class WebPlayerComponent implements OnInit, OnDestroy {
    private _subscriptions: { [key: string]: Subscription } = {};

    constructor(
        private readonly router: Router
    ) { }

    ngOnInit() {
        this._subscriptions ["routerSubscription"] = this.router.events.subscribe((event: RouterEvent) => {
            // other logic here
        });
    }

    ngOnDestroy() {
        Object.keys(this._subscriptions).map((key) => {
            this._subscriptions[key].unsubscribe();
        });
    }
}

这就是测试:

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { Router } from '@angular/router';

describe('PlayerComponent', () => {
    let component: PlayerComponent;
    let fixture: ComponentFixture<PlayerComponent>;

    beforeEach(async(() => {
        let router = {
            navigate: jasmine.createSpy(),
            events: {
                subscribe: jasmine.createSpy(),
                unsubscribe: jasmine.createSpy()
            }
        };


        TestBed.configureTestingModule({
            providers: [
                { provide: Router, useValue: router },
            ],
            declarations: [ PlayerComponent ]
        })
        .compileComponents();
    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(PlayerComponent);
        fixture.detectChanges();
        component = fixture.componentInstance;

    });

    it('should create', () => {
        expect(component).toBeTruthy();
    });
});
angular typescript karma-jasmine karma-runner
1个回答
1
投票

您确定routerSubscription是唯一的订阅吗?是否有其他订阅正在发生,可能导致取消订阅未定义?尝试导入RouterTestingModule而不是将其存根。 angular.io/api/router/testing/RouterTestingModule尝试将console.log(key)放在取消订阅的前面,以查看要取消订阅的密钥。

© www.soinside.com 2019 - 2024. All rights reserved.