Testing Angular component with unsubscribe Error during cleanup of component

后端 未结 10 1647
梦毁少年i
梦毁少年i 2021-01-30 10:37

I\'m testing a component which subscribe router params. Every test pass and everything works fine. But if I look in the console, I can see an error:

Error

相关标签:
10条回答
  • 2021-01-30 11:02

    In my case destroying the component after each test solved the problem. So you could try adding this to your describe function:

    afterEach(() => {
      fixture.destroy();
    })
    
    0 讨论(0)
  • 2021-01-30 11:06

    As explained by @randomPoison, the error is triggered when the component that uses unsubscribe is not initialised. However, calling fixture.detectChanges() is a solution for when the error is in the spec file of the respective component.

    But we might also be dealing with a FooComponent that creates BarComponent and BarComponent uses unsubscribe in its ngOnDestroy. Proper mocking must be done.

    I'd suggest a different approach to the subscription cleanup, one that is declarative and won't trigger such problems. Here's an example:

    export class BazComponent implements OnInit, OnDestroy {
      private unsubscribe$ = new Subject();
    
      ngOnInit(): void {
        someObservable$
          .pipe(takeUntil(this.unsubscribe$))
          .subscribe(...);
      }
    
      ngOnDestroy(): void {
        this.unsubscribe$.next();
        this.unsubscribe$.complete();
      }
    }
    

    More on this approach here

    0 讨论(0)
  • 2021-01-30 11:11

    The "Error during component cleanup" error message happens because when ngOnDestroy() is called, this.routeSubscription is undefined. This happens because ngOnInit() was never invoked, meaning that you never subscribed to the route. As described in the Angular testing tutorial, the component isn't initialized fully until you call fixture.detectChanges() the first time.

    Therefore, the correct solution is to add fixture.detectChanges() to your beforeEach() block right after the createComponent is called. It can be added any time after you create the fixture. Doing so will ensure that the component is fully initialized, that way component cleanup will also behave as expected.

    0 讨论(0)
  • 2021-01-30 11:11

    So my situation was similar, but not exactly the same: I'm just putting this here in case someone else finds it helpful. When unit testing with Jamine/Karma I was getting

     'ERROR: 'Error during cleanup of component','
    

    It turns out that was because I wasn't properly handling my observables, and they didn't have an error function on them. So the fix was adding an error function:

    this.entityService.subscribe((items) => {
          ///Do work
    },
      error => {
        this.errorEventBus.throw(error);
      });
    
    0 讨论(0)
  • 2021-01-30 11:19

    For me what fixed this error was inside of my component's ngOnDestroy, I wrapped my store dispatch and my unsubscribe in a try catch.

    ngOnDestroy(): void {
     try {
      this.store.dispatch(new foo.Bar(this.testThing()));
      if(this.fooBarSubscription) {
       this.fooBarSubscription.unsubscribe();
      }
     } catch (error) {
       this.store.dispatch(new foo.Bar(this.testThing()));
      }
    }
    
    0 讨论(0)
  • 2021-01-30 11:20

    I'm in a similar situation where I want to test a function in my component outside the context of the component itself.

    This is what worked for me:

    afterEach(() => {
      spyOn(component, 'ngOnDestroy').and.callFake(() => { });
      fixture.destroy();
    });
    
    0 讨论(0)
提交回复
热议问题