Angular 2 - test for change in route params

一笑奈何 提交于 2019-12-03 01:57:41

Firstly, you should use a Subject instead of an Observable. The observable only gets subscribed to once. So it will only emit the first set of params. With a Subject, you can keep emitting items, and the single subscription will keep getting them.

let params: Subject<Params>;

beforeEach(() => {
  params = new Subject<Params>();
  TestBed.configureTestingModule({
    providers: [
      { provide: ActivatedRoute, useValue: { params: params }}
    ]
  })
})

Then in your test just emit new values with params.next(newValue).

Secondly, you need to make sure to call tick(). This is how fakeAsync works. You control asynchronous task resolution. Since the observable as asychrounous, the moment we sent the event, it will not get to the subscriber synchronously. So we need to force synchronous behavior with tick()

Here is a complete test (Subject is imported from 'rxjs/Subject')

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

  _pageToShow: string;

  constructor(private _route: ActivatedRoute) {
  }

  ngOnInit() {
    this._route.params.forEach((params: Params) => {
      if (params['area']) {
        this._pageToShow = params['area'];
      }
    });
  }
}

describe('TestComponent', () => {
  let fixture: ComponentFixture<TestComponent>;
  let component: TestComponent;
  let params: Subject<Params>;

  beforeEach(() => {
    params = new Subject<Params>();
    TestBed.configureTestingModule({
      declarations: [ TestComponent ],
      providers: [
        { provide: ActivatedRoute, useValue: { params: params } }
      ]
    });
    fixture = TestBed.createComponent(TestComponent);
    component = fixture.componentInstance;
  });

  it('should change on route param change', fakeAsync(() => {
    // this calls ngOnInit and we subscribe
    fixture.detectChanges();

    params.next({ 'area': 'Terry' });

    // tick to make sure the async observable resolves
    tick();

    expect(component._pageToShow).toBe('Terry');

    params.next({ 'area': 'Billy' });
    tick();

    expect(component._pageToShow).toBe('Billy');
  }));
});

I prefer to get route params and data from ActivatedRouteSnapshot like this this.route.snapshot.params['type']

If you use the same way, you can test it like this

1) In your test providers

{provide: ActivatedRoute, useValue: {snapshot: { params: { type: '' } }}}

2) in your test spec

it('should...', () => {
   component.route.snapshot.params['type'] = 'test';
   fixture.detectChanges();
   // ...
});
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!