Angular 2 - 测试路由参数的变化 [英] Angular 2 - test for change in route params

查看:23
本文介绍了Angular 2 - 测试路由参数的变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 angular 2 组件,它响应路由参数的变化(组件不会从头开始重新加载,因为我们没有移出主路由.这是组件代码:

I have a component in angular 2 which responds to changes in the route parameters (the component doesn't reload from scratch because we're not moving out of the main route. Here's the component code:

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

这是一种享受,并且 _pageToShow 在导航中设置为适当的.

This works a treat and _pageToShow is set appropriate on navigation.

我正在尝试测试更改路线时的行为(因此第二次触发 observable 但它拒绝为我工作.)这是我的尝试:

I'm trying to test the behaviour on a change to the route (so a second trigger of the observable but it's refusing to work for me.) Here's my attempt:

it('sets PageToShow to new area if params.area is changed', fakeAsync(() => {
    let routes : Params[] = [{ 'area': "Terry" }];
    TestBed.overrideComponent(MyComponent, {
        set: {
            providers: [{ provide: ActivatedRoute,
                useValue: { 'params': Observable.from(routes)}}]
        }
    });

    let fixture = TestBed.createComponent(MyComponent);
    let comp = fixture.componentInstance;
    let route: ActivatedRoute = fixture.debugElement.injector.get(ActivatedRoute);
    comp.ngOnInit();

    expect(comp.PageToShow).toBe("Terry");
    routes.splice(2,0,{ 'area': "Billy" });

    fixture.detectChanges();
    expect(comp.PageToShow).toBe("Billy");
}));

但是当我运行它时,这会引发 TypeError: Cannot read property 'subscribe' of undefined 异常.如果我在没有 fixture.detectChanges(); 行的情况下运行它,它会因为第二个期望失败而失败.

But this throws a TypeError: Cannot read property 'subscribe' of undefined exception when I run it. If I run it without the fixture.detectChanges(); line it fails as the second expectation fails.

推荐答案

首先,你应该使用 Subject 而不是 Observable.observable 只被订阅一次.所以它只会发出第一组参数.使用 Subject,您可以继续发送项目,单个订阅将继续获取它们.

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 }}
    ]
  })
})

然后在您的测试中,只需使用 params.next(newValue) 发出新值.

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

其次,您需要确保调用 tick().这就是 fakeAsync 的工作原理.您控制异步任务解析.由于 observable 是异步的,所以在我们发送事件的那一刻,它不会同步到达订阅者.所以我们需要用 tick()

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()

这是一个完整的测试(Subject是从'rxjs/Subject'导入的)

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');
  }));
});

这篇关于Angular 2 - 测试路由参数的变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆