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.

2
  • 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. Commented Feb 10, 2017 at 7:38
  • 1
    @JacobNotte This worked for me! Had just to ensure that this.subscription was not undefined! Commented Mar 1, 2017 at 13:23

2 Answers 2

2

Just use observer when mock your service:

{
    provide: ActivatedRoute,
    useValue: { data: Observable.of({ name: 'Stepan' }) }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for answer, I tried params: Observable.of({name: 'Stepan'}) instead of data: Observable.of({ name: 'Stepan' }), now its working fine.
1

You should import Subscription first.

import { Subscription } from 'rxjs/Subscription';

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.