Arw*_*win 3 angular2-routing angular2-testing angular
假设我想简单地对一个组件进行单元测试,该组件采用从路径的一部分获取的参数.例如,我的组件的ngOnInit看起来像这样:
ngOnInit() {
this.route.parent.params.switchMap((params: Params) => this.service.getProject(params['projectId']))
.subscribe((project: Project) => this.update(project));
}
Run Code Online (Sandbox Code Playgroud)
我现在该怎么做:1:设置我的测试,以便组件创建工作,所以我可以单元测试其他部分
用回答编辑 - 示例ActivatedRouteStub应该使用也有可观察的params的父进行扩展,我应该使用useClass而不是useValue(忘了改回来):
@Injectable()
export class ActivatedRouteStub {
// ActivatedRoute.params is Observable
private subject = new BehaviorSubject(this.testParams);
params = this.subject.asObservable();
// Test parameters
private _testParams: {};
get testParams() { return this._testParams; }
set testParams(params: {}) {
this._testParams = params;
this.subject.next(params);
}
// ActivatedRoute.snapshot.params
get snapshot() {
return { params: this.testParams };
}
// ActivatedRoute.parent.params
get parent() {
return { params: this.subject.asObservable() };
}
}
Run Code Online (Sandbox Code Playgroud)
2:在我的UnitTest中为projectId提供一个值?
来自angular2文档的示例似乎不适用于switchMap,甚至根本不适用(我从那里使用过ActivatedRouteStub,但到目前为止没有运气 - params总是未定义的).
编辑答案:
describe('ProjectDetailsComponent', () => {
let component: ProjectDetailsComponent;
let fixture: ComponentFixture<ProjectDetailsComponent>;
let activatedRoute: ActivatedRouteStub;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule.withRoutes([{ path: 'projects/:projectId', component: ProjectDetailsComponent }])],
declarations: [ProjectDetailsComponent],
schemas: [NO_ERRORS_SCHEMA],
providers: [{ provide: ProjectsService, useClass: ProjectsServiceStub }, {provide: ActivatedRoute, useClass: ActivatedRouteStub}]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ProjectDetailsComponent);
component = fixture.componentInstance;
activatedRoute = fixture.debugElement.injector.get(ActivatedRoute);
activatedRoute.testParams = { projectId: '123'};
fixture.detectChanges();
});
fit('should create', () => {
expect(component).toBeTruthy();
});
});
Run Code Online (Sandbox Code Playgroud)
如果你没有正确创建存根,那么params将被定义的唯一方法是.看看电话
this.route.parent.params.switchMap
Run Code Online (Sandbox Code Playgroud)
params是一个两层深的嵌套属性.所以作为普通的JS对象你需要
let mock = {
parent: {
params: Observable.of(...)
}
}
Run Code Online (Sandbox Code Playgroud)
如果你想使用一个类,你可以使用类似的东西
class ActivatedRouteStub {
parent = {
params: Observable.of({})
};
set testParams(params: any) {
this.parent.params = Observable.of(params);
}
}
Run Code Online (Sandbox Code Playgroud)
你只需使用一个setter testParams来设置值parent.params.那么当你这样做时stub.testParams = whatever,该值将被设置在the observable上parent.params.
除了上面有关如何实现此功能的说明之外,您的配置中也存在错误
{provide: ActivatedRoute, useValue: ActivatedRouteStub}
Run Code Online (Sandbox Code Playgroud)
useValue应该是你创建的对象.所以你要传递一个类,那个类将是注入的,而不是类的实例.如果你想让Angular创建它,那么你应该使用useClass.否则,您应该自己创建实例,并将该实例用作值
{provide: ActivatedRoute, useValue: new ActivatedRouteStub() }
Run Code Online (Sandbox Code Playgroud)
注意实例化.
如果有人最终在 Angular 7 中遇到此问题,Angular 文档给出了一个清晰的示例,说明如何测试依赖于 ActivatedRoute 服务的组件。请参阅: https: //v7.angular.io/guide/testing#activatedroutestub。只是和上面的回答有点不同。
| 归档时间: |
|
| 查看次数: |
10660 次 |
| 最近记录: |