如何模拟route.snapshot.params?

38

在我的Angular 4组件中,我有类似以下的东西:

constructor(private route: ActivatedRoute) {
}

ngOnInit() {
  this.myId = this.route.snapshot.params['myId'];
}

我正在尝试创建一个模拟,它应该看起来像下面这样:

And I'm trying to create a mock that suppose to look like follows:

class MockActivatedRoute extends ActivatedRoute {
  public params = Observable.of({ myId: 123 });
}    

我的测试失败,显示如下错误:

TypeError: Cannot read property 'params' of undefined.

我该如何模拟它?我是否误解了ActivatedRoute的正确使用方法,应该在组件中更好地使用router.subscribe?我看到一些复杂的例子,在这些例子中人们模拟快照本身,但对我而言这看起来太过复杂。


测试本身非常简单:

describe('ngOnInit', () => {
it('should set up initial state properly',
  () => {
  const component = TestBed.createComponent(MyComponent).componentInstance;
    component.ngOnInit();
    expect(component.myId).toEqual('123');
  });
});

如果我只是将测试中的一个方法更改为以下内容-测试就能正常工作:

ngOnInit() {
    //this.myId = this.route.snapshot.params['myId'];
    this.route.params.subscribe(params => {
    this.myId = params['myId'];
    });
}

显然,我需要模拟已激活的快照,但是否有更好的方法?


我也尝试过类似于 const fakeRoutes: Routes = [{path: 'info', data: { catalogId: '123' }, component: StatusComponent},] 然后 RouterTestingModule.withRoutes(fakeRoutes) 的操作。不确定这种语法是否被支持。 - and85
你是在尝试在单元测试中使用这个吗?如果是的话,你能贴出那段代码吗? - LLai
你得到了“未定义”的参数,是因为你的模拟(mock)正在模拟可观察对象 this.route.params(返回一个可观察对象),而不是快照 this.route.snapshot.params(返回参数对象)。 - LLai
是的,谢谢。快照也使用了参数,所以我认为它应该足够聪明,能够理解我模拟的参数。这意味着如果我想要模拟快照和参数,我需要复制并粘贴参数两次。无论如何,我昨天已经成功解决了这个问题,感谢你的帮助。 - and85
3个回答

51

好的,我找到了一种简单的方法来模拟 ActivatedRoute 快照。类似这样的方式对我有效:

providers: [MyComponent, {
  provide: ActivatedRoute,
  useValue: {snapshot: {params: {'myId': '123'}}}
}

谢谢 :)


40

如果使用route.snapshot.paramMap.get('uuid')代替:

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

{
    provide: ActivatedRoute, useValue:
        { snapshot: { paramMap: convertToParamMap( { 'uuid': '99-88-77' } ) } }
}

1
这正是我所需要的,谢谢!否则会出现“this.route.snapshot.paramMap.get不是函数”的错误。 - michaeak
非常感谢,你的回答救了我的一天。 - Alaa El-din Ahmed Muhammad

2

不要模拟它,你可以获取原始路由并简单地窥视参数

   let route: ActivatedRoute;

        beforeEach(() => {
          TestBed.configureTestingModule(...).compileComponents();

          route = TestBed.get(ActivatedRoute);
   })

   it("test",  () => {
      const spyRoute = spyOn(route.snapshot.paramMap, "get")
       spyRoute.and.callFake((paramNameToRead) => {

        switch (paramNameToRead) {
            case "id" : {
                return "value1";
            }
            case "foo" : {
                return null;
            }
            case "bar" : {
                return baz;
            }

        }


    });

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接