如何单元测试Angular 2路由参数

问题描述 投票:2回答:2

假设我想简单地对一个组件进行单元测试,该组件采用从路径的一部分获取的参数。例如,我的组件的ngOnInit看起来像这样:

  ngOnInit() {
    this.route.parent.params.switchMap((params: Params) => this.service.getProject(params['projectId']))
      .subscribe((project: Project) => this.update(project));
  }

我现在该怎么做: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() };
    }
}

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();
  });
});
angular angular2-routing angular2-testing
2个回答
5
投票

如果你没有正确创建存根,那么params将被定义的唯一方法是。看看电话

this.route.parent.params.switchMap

params是一个两层深的嵌套属性。所以作为普通的JS对象你需要

let mock = {
  parent: {
    params: Observable.of(...)
  }
}

如果你想使用一个类,你可以使用类似的东西

class ActivatedRouteStub {

  parent = {
    params: Observable.of({})
  };

  set testParams(params: any) {
    this.parent.params = Observable.of(params);
  }
}

你只需在testParams上使用一个setter来设置parent.params的值。那么当你做stub.testParams = whatever时,该值将设置在parent.params的可观察量上。

UPDATE

除了上面有关如何实现此功能的说明之外,您的配置中也存在错误

{provide: ActivatedRoute, useValue: ActivatedRouteStub}

useValue应该是你创造的对象。所以你要传递一个类,那个类将是注入的,而不是类的实例。如果你想让Angular创建它,那么你应该使用useClass。否则,您应该自己创建实例,并将该实例用作值

{provide: ActivatedRoute, useValue: new ActivatedRouteStub() }

注意实例化。


0
投票

如果有人最终在Angular 7中遇到此问题,Angular文档会给出一个明确的示例,说明如何测试依赖于ActivatedRoute服务https://angular.io/guide/testing#activatedroutestub的组件。与上面的回答略有不同。

© www.soinside.com 2019 - 2024. All rights reserved.