How to unit test a component that depends on parameters from ActivatedRoute?

半城伤御伤魂 提交于 2019-11-27 05:07:01

问题


I am unit testing a component that is used to edit an object. The object has an unique id that is used in order to grab the specific object from an array of objects that are hosted in a service. The specific idis procured through a parameter that is passed via routing, specifically through the ActivatedRoute class.

The constructor is as follows:

 constructor(private _router:Router, private _curRoute:ActivatedRoute, private _session:Session) {
}

ngOnInit() {
    this._curRoute.params.subscribe(params => {
        this.userId = params['id'];
        this.userObj = this._session.allUsers.filter(user => user.id.toString() === this.userId.toString())[0];

I want to run basic unit tests on this component. However, I am not sure as to how I can inject the id parameter, and the component needs this parameter.

By the way: I already have a mock for the Session service, so no worries there.


回答1:


The simplest way to do this is to just use the useValue attribute and provide an Observable of the value you want to mock.

RxJS < 6

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
...
{
  provide: ActivatedRoute,
  useValue: {
    params: Observable.of({id: 123})
  }
}

RxJS >= 6

import { of } from 'rxjs';
...
{
  provide: ActivatedRoute,
  useValue: {
    params: of({id: 123})
  }
}



回答2:


I have figured out how to do this!

Since ActivatedRoute is a service, a mock service for it can be established. Let's call this mock service MockActivatedRoute. We will extend ActivatedRoute in MockActivatedRoute, as follows:

class MockActivatedRoute extends ActivatedRoute {
    constructor() {
        super(null, null, null, null, null);
        this.params = Observable.of({id: "5"});
    }

The line super(null, ....) initializes the super class, which has four mandatory parameters. However, in this instance, we need nothing from any of these parameters, so we initialize them to null values. All we need is the value of params which is an Observable<>. Therefore, with this.params, we override the value of params and initialize it to be the Observable<> of the parameter on which the test subject is relying.

Then, as any other mock service, just initialize it and override the provider for the component.

Good luck!




回答3:


Here is how I tested it in angular 2.0 latest...

import { ActivatedRoute, Data } from '@angular/router';

and in Providers section

{
  provide: ActivatedRoute,
  useValue: {
    data: {
      subscribe: (fn: (value: Data) => void) => fn({
        yourData: 'yolo'
      })
    }
  }
}



回答4:


Just add a mock of the ActivatedRoute:

providers: [
  { provide: ActivatedRoute, useClass: MockActivatedRoute }
]

...

class MockActivatedRoute {
  // here you can add your mock objects, like snapshot or parent or whatever
  // example:
  parent = {
    snapshot: {data: {title: 'myTitle ' } },
    routeConfig: { children: { filter: () => {} } }
  };
}



回答5:


For some folks working on Angular > 5, if Observable.of(); is not working then they can use just of() by importing import { of } from 'rxjs';



来源:https://stackoverflow.com/questions/38356084/how-to-unit-test-a-component-that-depends-on-parameters-from-activatedroute

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!