Col*_*Cox 70 unit-testing angular2-routing angular2-testing angular
我是一个单元测试用于编辑对象的组件.该对象具有唯一性id,用于从服务中托管的对象数组中获取特定对象.具体id是通过路由传递的参数获得的,特别是通过ActivatedRoute类传递.
构造函数如下:
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];
Run Code Online (Sandbox Code Playgroud)
我想对这个组件运行基本的单元测试.但是,我不确定如何注入id参数,组件需要此参数.
顺便说一下:我已经有了Session服务的模拟,所以不用担心.
zma*_*anc 107
最简单的方法是使用该useValue属性并提供要模拟的值的Observable.
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
...
{
provide: ActivatedRoute,
useValue: {
params: Observable.of({id: 123})
}
}
Run Code Online (Sandbox Code Playgroud)
dim*_*maf 22
在 angular 8+ 中有RouterTestingModule,您可以使用它来访问组件的ActivatedRoute或Router。您也可以将路由传递给RouterTestingModule并为请求的路由方法创建间谍。
例如在我的组件中,我有:
ngOnInit() {
if (this.route.snapshot.paramMap.get('id')) this.editMode()
this.titleService.setTitle(`${this.pageTitle} | ${TAB_SUFFIX}`)
}
Run Code Online (Sandbox Code Playgroud)
在我的测试中,我有:
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ProductLinePageComponent ],
schemas: [NO_ERRORS_SCHEMA],
imports: [
RouterTestingModule.withRoutes([])
],
})
.compileComponents()
}))
beforeEach(() => {
router = TestBed.get(Router)
route = TestBed.get(ActivatedRoute)
})
Run Code Online (Sandbox Code Playgroud)
后来在“它”部分:
it('should update', () => {
const spyRoute = spyOn(route.snapshot.paramMap, 'get')
spyRoute.and.returnValue('21')
fixture = TestBed.createComponent(ProductLinePageComponent)
component = fixture.componentInstance
fixture.detectChanges()
expect(component).toBeTruthy()
expect(component.pageTitle).toBe('Edit Product Line')
expect(component.formTitle).toBe('Edit Product Line')
// here you can test the functionality which is triggered by the snapshot
})
Run Code Online (Sandbox Code Playgroud)
类似的,我认为你可以paramMap通过spyOnPropertyjasmine的方法直接测试,通过返回一个observable或者使用rxjs弹珠。它可能会节省一些时间,而且不需要维护额外的模拟类。希望它是有用的,它是有道理的。
Col*_*Cox 16
我已经想出怎么做了!
既然ActivatedRoute是服务,就可以建立一个模拟服务.我们称之为模拟服务MockActivatedRoute.我们将扩大ActivatedRoute在MockActivatedRoute,具体如下:
class MockActivatedRoute extends ActivatedRoute {
constructor() {
super(null, null, null, null, null);
this.params = Observable.of({id: "5"});
}
Run Code Online (Sandbox Code Playgroud)
该行super(null, ....)初始化超类,它有四个必需参数.但是,在这种情况下,我们不需要任何这些参数,因此我们将它们初始化为null值.我们需要的是价值params这是一个Observable<>.因此,使用this.params,我们覆盖它的值params并将其初始化Observable<>为测试主体所依赖的参数.
然后,与任何其他模拟服务一样,只需初始化它并覆盖组件的提供程序.
祝好运!
这是我在角度2.0最新测试中的方式...
import { ActivatedRoute, Data } from '@angular/router';
Run Code Online (Sandbox Code Playgroud)
在提供者部分
{
provide: ActivatedRoute,
useValue: {
data: {
subscribe: (fn: (value: Data) => void) => fn({
yourData: 'yolo'
})
}
}
}
Run Code Online (Sandbox Code Playgroud)
只需添加 ActivatedRoute 的模拟:
providers: [
{ provide: ActivatedRoute, useClass: MockActivatedRoute }
]
Run Code Online (Sandbox Code Playgroud)
...
class MockActivatedRoute {
// here you can add your mock objects, like snapshot or parent or whatever
// example:
parent = {
snapshot: {data: {title: 'myTitle ' } },
routeConfig: { children: { filter: () => {} } }
};
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
45360 次 |
| 最近记录: |