【问题标题】:Unit testing routes with Mock ActivatedRoute configuration使用 Mock ActivatedRoute 配置对路由进行单元测试
【发布时间】:2019-05-24 09:51:58
【问题描述】:

我正在为具有路由的组件配置测试规范,我还定义了具有如下依赖关系的规范。并且 ActivatedRoute 具有这些属性,但是在调试我的测试规范时我没有看到它的对象/实例被创建。我还提到了模拟 ActivatedRoute 的不同方法,但没有任何帮助。如果我做错了什么请纠正我

class UserInfotypeDetailComponent implements OnInit, OnDestroy {
    constructor(
        private userInfotypeDetailService: UserInfotypeDetailService,
        private appLookupService: AppLookupService,
        private router: Router,
        private activatedRoute: ActivatedRoute
    ) {}

 performAction(event: { action: string; objectKey: string | null }) {
    let extras: any = { relativeTo: this.activatedRoute };
    if (event.objectKey) {
          extras.queryParams = { objectKey: event.objectKey };
    }

    switch (event.action) {
      case "new":
      case "edit":
      case "copy":
      case "view":
        this.router.navigate([event.action], extras);
        break;
      case "delete":
        this.deleteRecord(event.objectKey as string);
    }
  }

}

这是我的路线:

{
        path: "infotype/:id",
        component: UserInfotypeDetailComponent,
        outlet: "slidein",
        children: [
          {
            path: "new",
            component: UserRecordFormComponent,
            data: { actionId: "A", buttonDesc: "Save" }
          },
          {
            path: "edit",
            component: UserRecordFormComponent,
            data: { actionId: "E", buttonDesc: "Update" }
          },
          {
            path: "copy",
            component: UserRecordFormComponent,
            data: { actionId: "C", buttonDesc: "Save" }
          },
          {
            path: "view",
            component: UserRecordFormComponent,
            data: { actionId: "V", actionDesc: "View" }
          }
        ]
      }

我的测试规范如下:

beforeEach(async(() => {
        TestBed.configureTestingModule({
            imports: [
              RouterTestingModule.withRoutes([]),
                BrowserAnimationsModule,
                RouterModule
            ],
            declarations: [
                UserInfotypeDetailComponent
            ],
            providers: [
                { provide: ActivatedRoute, useValue: {
                                          outlet: "slidein",
                                          params: of({ 
                                              id: "0009"
                                          })
                                      }
                },
                { provide: AppLookupService, useClass: AppLookupServiceStub },
                { provide: UserInfotypeDetailService, useClass: UserInfotypeDetailServiceStub },
                { provide: Router, useClass: AppRouterStub }
            ],
            schemas: [NO_ERRORS_SCHEMA]
        }).compileComponents();
    }));

    class AppRouterStub {
        navigate() {}
    }

和测试用例:

it('make expect calls to router navigate', fakeAsync(() => {
      let router = TestBed.get(Router);
      let spy = spyOn(router, 'navigate');

      component.performAction(event);

      let extras: any = { relativeTo: ActivatedRoute };
      if (event.objectKey) {
        extras.queryParams = { objectKey: event.objectKey };
      }
      fixture.detectChanges();

      expect(spy).toHaveBeenCalledWith([event.action], extras);
    }))

它抛出的错误是:

“间谍导航已被调用 [ [ 'edit' ], Object({ relativeTo: Function, queryParams: Object({ objectKey: '36353539363A393C3535353E352525252525253E3E3E3E363738363735363E35363536353535' }) 'edit}]] 但实际调用, Object({ relativeTo: Object({ snapshot: Object({ }), parent: Object({ params: Subject({ _isScalar: false, 观察者: [ ], closed: false, isStopped: false, hasError: false, throwedError: null }) }),参数:主题({ _isScalar:假,观察者:[],关闭:假,isStopped:假,hasError:假,抛出错误:空}),查询参数:主题({_isScalar:假,观察者:[ ],关闭:False,ISStopped:False,HasError:False,thrownerror:null}),testparams:对象({id:'0009'})}),queryparams:对象({objectkey:'3635353925252525252525252525252525252525252525252525252525252525252035252525252525252525353530353535252525252525252525353525252353536/) 。”

【问题讨论】:

    标签: angular typescript unit-testing karma-jasmine


    【解决方案1】:

    失败是因为

    let extras: any = { relativeTo: ActivatedRoute };
    

    您实际上使用的是 Angular 的 ActivatedRoute,但您应该使用的是您在 providers 中定义的 useValue。

    在组件的constructor中创建activatedRoute public,这样我们就可以访问了

    public activatedRoute: ActivatedRoute,
    public router : Router
    

    试试:

    it('make expect calls to router navigate', fakeAsync(() => {
          spyOn(component.router, 'navigate');
    
          component.performAction(event);
          // I hope you have defined "event" somewhere in code, because I can't see
          // it anywhere here !
    
          let extras: any = { relativeTo: component.activatedRoute};
          if (event.objectKey) {
            extras.queryParams = { objectKey: event.objectKey };
          }
    
          expect(component.router.navigate).toHaveBeenCalledWith([event.action], extras);
        }))
    

    【讨论】:

    • 我确实尝试了上面的建议,它仍然返回相同的错误。
    • @SoujanyaJ 你能按照我的建议和错误截图分享新代码吗?如果您按照我的建议使用了component.activatedRoute,则错误显示Object({ snapshot: Object({ }) 等不应该出现。一旦你在你的问题中提供了这两个,请告诉我
    猜你喜欢
    • 1970-01-01
    • 2020-08-13
    • 1970-01-01
    • 2015-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多