3

I have sample TestComp with ngOnInit and ngOnDestroy methods and ActivatedRoute subscription.

@Component({
    selector: 'test',
    template: '',
})
export class TestComp implements OnInit, OnDestroy {

    constructor (
        private route: ActivatedRoute
    ) {
    }

    ngOnInit() {
        this.subscription = this.route.data
            .subscribe(data => {
                console.log('data', data.name);
            })
        ;
    }

    ngOnDestroy() {
        this.subscription.unsubscribe();
    }
}

I am getting "Cannot read property 'unsubscribe' of undefined" when I call ngOnDestroy method from spec file (or when I am running multiple tests).

My spec file:

describe('TestComp', () => {
    let comp: TestComp;
  let fixture: ComponentFixture<TestComp>;

  beforeEach(async(() => {
    TestBed
    .configureTestingModule({
      declarations: [TestComp],
      imports: [RouterTestingModule],
      providers: [
        {
        provide: ActivatedRoute,
        useValue: {
          data: {
            subscribe: (fn: (value: Data) => void) => fn({
              name: 'Stepan'
            })
          }
        }
      }
        // { //Also tried this
        //   provide: ActivatedRoute,
        //   useValue: {
        //     params: Observable.of({name: 'Stepan'})
        //   }
        // }
      ]
    })
    .compileComponents()
    .then(() => {
          fixture = TestBed.createComponent(TestComp);        
          fixture.detectChanges();
    })
    }));

  it('TestComp successfully initialized', () => {
    fixture.componentInstance.ngOnInit();
    expect(fixture.componentInstance).toBeDefined()
    fixture.componentInstance.ngOnDestroy();
  });
});

I am passing ActivatedRoute value based on answers here, but I am getting error. So my question is - what should I pass as ActivatedRoute to make it possible to subscribe and unsubscribe? Example Plunker.

Community
  • 1
  • 1
styopdev
  • 2,604
  • 4
  • 34
  • 55
  • 1
    it's a good practice to put a conditional `if (this.subscription)` around the unsubscription. I've just tried the testcode and put a `setTimeout` of 500ms on the ngOnDestroy function call in your test and then the test passes. I guess it takes some time until the subscription is actually initialised. – Jacob Notte Feb 10 '17 at 07:38
  • 1
    @JacobNotte This worked for me! Had just to ensure that `this.subscription` was not `undefined`! – SrAxi Mar 01 '17 at 13:23

2 Answers2

2

Just use observer when mock your service:

{
    provide: ActivatedRoute,
    useValue: { data: Observable.of({ name: 'Stepan' }) }
}
VadimB
  • 5,533
  • 2
  • 34
  • 48
  • Thanks for answer, I tried ``params: Observable.of({name: 'Stepan'})`` instead of ``data: Observable.of({ name: 'Stepan' })``, now its working fine. – styopdev Feb 10 '17 at 11:05
1

You should import Subscription first.

import { Subscription } from 'rxjs/Subscription';
Mertcan Diken
  • 14,483
  • 2
  • 26
  • 33