How to Unit Test Angular 2 routing params

The only way params would be undefined is if you're not creating the stub correctly. Look at the call

this.route.parent.params.switchMap

params is a nested property two levels deep. So as plain JS object you would need

let mock = {
  parent: {
    params: Observable.of(...)
  }
}

If you want to use a classes, you could use something like

class ActivatedRouteStub {

  parent = {
    params: Observable.of({})
  };

  set testParams(params: any) {
    this.parent.params = Observable.of(params);
  }
}

You just use a setter on the testParams to set the value of the parent.params. So then when you do stub.testParams = whatever, the value will be set on the observable of the parent.params.

UPDATE

Aside from the above explanation on how you can implement this, you also have an error in your configuration

{provide: ActivatedRoute, useValue: ActivatedRouteStub}

useValue is supposed to be an object that you create. So you are passing a class, and that class will be what is injected, not an instance of the class. If you want Angular to create it, then you should use useClass. Otherwise you should create the instance yourself, and use that instance as the value

{provide: ActivatedRoute, useValue: new ActivatedRouteStub() }

Notice the instantiation.


If anybody ends up having this problem with Angular 7, the Angular docs give a clear example how to test components dependent on the ActivatedRoute service. See: https://v7.angular.io/guide/testing#activatedroutestub. Just a bit different from the responses above.