如何对使用router.paramMap的Angular 4组件进行单元测试

如何对使用router.paramMap的Angular 4组件进行单元测试,angular,jasmine,karma-jasmine,Angular,Jasmine,Karma Jasmine,我是angular 4的新手,尝试从单元测试中测试angular 4功能router.paramMap中的一个,以休闲方式读取路由参数,并在我的应用程序中按预期工作 constructor(private router:Router, private actRoute:ActivatedRoute) { } ngOnInit() { this.router.paramMap.subscribe(params => { params.get(id); })

我是angular 4的新手,尝试从单元测试中测试angular 4功能router.paramMap中的一个,以休闲方式读取路由参数,并在我的应用程序中按预期工作

constructor(private router:Router, private actRoute:ActivatedRoute) {
}

ngOnInit() {
    this.router.paramMap.subscribe(params => {
        params.get(id);
    })
......
}
但在运行单元测试时,我得到了一个错误,即不能调用undefined的subscribe方法,即使我传递如下route参数

{
  provide: ActivatedRoute,
  useValue: { params: Observable.of({id: 1}) }
}

请建议

我们目前正在使用:

    { provide: ActivatedRoute, useValue: { 'params': Observable.from([{ 'id': '1'}]) } },

您的代码有一个问题,为了从URL获取参数,您必须以不同的方式编写内容

constructor(private router:Router, private actRoute:ActivatedRoute) {
}

ngOnInit() {
    this.router.paramMap
        .switchMap((params: ParamMap) => {
            params.get(id);
            ....
        })
        .subscribe((....) => {
            ....
        })
}

您需要提供
paramMap
,而不是
params
paramMap
应该是
@angular/routing
中的
paramMap
类型,因此可以使用
@angular/routing
中的
ConvertTopParamMap()
方法将普通对象转换为
paramMap

您可以提供模拟ActivatedRoute,如下所示:

import { convertToParamMap} from '@angular/router';
....
.....

{
      provide: ActivatedRoute,
      useValue: { paramMap: Observable.of(convertToParamMap({id: 1})) }
}

我正在使用一种稍微不同的方法来获取组件中的参数:

this.id = this.route.snapshot.paramMap.get('id');
这就是茉莉花测试对我起作用的原因:

{
      provide: ActivatedRoute,
      useValue: {
        snapshot: {
          paramMap: convertToParamMap({id: 1})
        }
      }
}

对于任何需要对组件进行测试的人来说,当组件确实有某个路由参数时,以及当组件没有某个路由参数时(如
/product
/product/:id
),以下内容适用于我:

组成部分:

this.id = this.route.snapshot.paramMap.get('id');
导出类PageProductComponent实现OnInit{
id:string | null=null;
构造函数(私有只读activatedRoute:activatedRoute){}
ngOnInit():void{
this.id=this.activatedRoute.snapshot.paramMap.get('id');
}
}
测试:

description('PageProductComponent',()=>{
let组件:PageProductComponent;
let夹具:组件夹具;
让debugEl:DebugElement;
const makeCompiledTestBed=(提供程序?:对象):void=>{
常量moduleDef:TestModuleMetadata={
进口:[
路由器测试模块,
],
声明:[PageProductComponent],
提供者:[]
};
if(moduleDef.providers&&provider){
moduleDef.providers.push(提供程序);
}
configureTestingModule(moduleDef).compileComponents();
};
const setupTestVars=():void=>{
fixture=TestBed.createComponent(PageProductComponent);
组件=fixture.componentInstance;
debugEl=fixture.debugElement;
fixture.detectChanges();
};
description('当URL参数中未提供ID时',()=>{
beforeach(异步(makeCompiledTestBed));
每次之前(设置测试变量);
它('应列出所有产品',()=>{
//...
});
});
description('在URL参数中提供ID时',()=>{
beforeach(异步(()=>{
制作编译测试床({
提供:激活的路由,
使用价值:{
快照:{
paramMap:convertToParamMap({id:1234})
}
}
});
}));
每次之前(设置测试变量);
它('应该显示特定的产品',()=>{
//...
});
});
});

谢谢@Lotte Lemmens的回答,但我又遇到了一个问题-TypeError:params.get不是函数,有什么解决方案吗?使用paramMap是否还有其他价值?这是.Routh.PARAM.Sube(PAR= > {const IDOFF PARAMS= PAR.ID})这应该是上面提到的可测试的,不知道TurnTopPARAMMAP方法存在。为我节省了大量的时间,让我不用自己去补课。谢谢