Ori*_*nss 3 dependencies unit-testing typescript angular angular5
我目前正在开发旧版 Angular 5 代码,除了使用 Angular CLI 生成组件时的默认测试之外,该代码没有任何单元测试。
\n\n该项目正在使用 Angular Material 5 RC0,单元测试似乎没有考虑我的模块的依赖关系。
\n\n应用程序模块.ts:
\n\n@NgModule({\n declarations: [\n AppComponent,\n /* My module components... */\n ],\n imports: [\n BrowserModule,\n FormsModule,\n HttpModule,\n ReactiveFormsModule,\n BrowserAnimationsModule,\n routing,\n DialogsModule,\n SharedModule ,\n MaterialModule,\n MatListModule, // It\'s the module that should be needed\n MatSidenavModule,\n ToastrModule.forRoot({\n timeOut: 5000,\n positionClass: \'toast-bottom-right\',\n preventDuplicates: true\n }),\n HttpClientModule,\n TableFactoryModule\n ],\n providers: [\n /* My module services */,\n AuthGuard\n ],\n bootstrap: [AppComponent]\n\n})\nexport class AppModule {\n\n}\nRun Code Online (Sandbox Code Playgroud)\n\n应用程序组件.ts:
\n\nimport { Component, Input, ViewChild } from \'@angular/core\';\nimport { Router, RouterModule, ActivatedRoute } from \'@angular/router\';\nimport { HttpErrorResponse } from \'@angular/common/http\';\nimport { JwtHelperService } from \'@auth0/angular-jwt\';\nimport * as _ from \'lodash\';\n\nimport { Subscription } from \'rxjs/Subscription\';\nimport { ToastrService } from \'ngx-toastr\';\n\nimport { UsersService } from \'app/services/users.service\';\nimport { ComplexesService } from \'app/services/complexes.service\';\nimport { ActivatedUserService } from \'app/shared/activateduser.service\';\nimport { ActivatedComplexesService } from \'app/shared/activatedcomplexes.service\';\n\nimport { User } from \'app/user\';\nimport { Complex } from \'./complex/complex\'\nimport { MatSidenav } from \'@angular/material\';\nimport { MatList } from \'@angular/material/list\'\n\n\n@Component({\n selector: \'app-root\',\n templateUrl: \'./app.component.html\',\n styleUrls: [\'./app.component.css\']\n})\nexport class AppComponent {\n title = \'app works!\';\n isConnected = false;\n private subscription;\n private currentUser: User;\n userSubscription: Subscription;\n complexesSubscription: Subscription;\n @ViewChild(MatSidenav) sidenav: MatSidenav;\n\n constructor(\n private usersService: UsersService,\n private complexesService: ComplexesService,\n private router: Router,\n private toastr: ToastrService,\n private activatedUser: ActivatedUserService,\n private activatedComplexes: ActivatedComplexesService,\n ){\n }\n ngOnInit() {\n let getToken = this.usersService.isConnected();\n if (getToken) {\n this.getComplexes();\n this.userGetById(); \n }\n else\n this.router.navigate([\'\']);\n\n this.userSubscription = this.activatedUser.activatedUser$\n .subscribe(user => {\n if(user) {\n this.currentUser = user;\n this.sidenav.open();\n }\n });\n }\n logout(){\n this.usersService.logout();\n this.isConnected = this.usersService.isConnected();\n this.router.navigate([\'\']);\n }\n ngOnDestroy() {\n this.userSubscription.unsubscribe();\n this.complexesSubscription.unsubscribe(); \n }\n\n private userGetById(){\n let token = JSON.parse(localStorage.getItem(\'futbakCurrentUser\'));\n let jwtHelperService: JwtHelperService = new JwtHelperService({});\n let currentUser = jwtHelperService.decodeToken(token);\n this.usersService.getByID(currentUser.id).subscribe(\n (res) => {\n this.currentUser = res\n }, (err: HttpErrorResponse) => {\n if (err.error instanceof Error) {\n // A client-side or network error occurred. Handle it accordingly.\n this.toastr.error("Une erreur est survenue : "+err.error.message\xc2\xa0 , \'\', { closeButton: true });\n } else {\n this.toastr.error("Une erreur est survenue code : "+ err.status+", message : "+err.statusText, \'\', { closeButton: true });\n }\n },\n () => {\n if(this.currentUser.role == \'superadmin\' || this.currentUser.role == \'complexmanager\') {\n this.activatedUser._activatedUser$.next(this.currentUser)\n }\n if(this.currentUser.role == \'superadmin\') {\n this.router.navigate([\'usersList\']);\n this.getComplexes();\n } else if (this.currentUser.role == \'complexmanager\') {\n this.router.navigate([\'admins/\'+this.currentUser._id])\n } else {\n this.toastr.error("Vous n\'avez pas les droits pour acc\xc3\xa8der \xc3\xa0 l\'application.",\'\',{closeButton :true});\n }\n });\n }\n\n private getComplexes(){\n return this.complexesService.get()\n .subscribe(\n res => {\n if(res)\n this.activatedComplexes._activatedComplexes$.next(res)\n }, (err: HttpErrorResponse) => {\n if (err.error instanceof Error) {\n this.toastr.error("Une erreur est survenue : "+err.error.message\xc2\xa0 , \'\', { closeButton: true });\n } else {\n this.toastr.error("Une erreur est survenue code : "+ err.status+", message : "+err.statusText, \'\', { closeButton: true }); \n }\n },\n () => {\n });\n }\n\n }\nRun Code Online (Sandbox Code Playgroud)\n\n失败的测试:
\n\nit(\'should create the app\', async(() => {\n const fixture = TestBed.createComponent(AppComponent);\n const app = fixture.debugElement.componentInstance;\n expect(app).toBeTruthy();\n }));\nRun Code Online (Sandbox Code Playgroud)\n\n应用程序组件.html:
\n\n<mat-sidenav-container fullscreen >\n\n <mat-sidenav #sidenav mode="side" disableClose>\n <!-- sidenav content -->\n\n <div><img src="./assets/logo.png" class="logo" ></div>\n <div class="title-app">\n <h2>Admin</h2>\n </div>\n\n <mat-nav-list>\n <a mat-list-item routerLinkActive="active" routerLink="[\'usersList\']">\n <!-- <mat-icon fontSet="fa" fontIcon="fa-users" ></mat-icon> -->\n <i class="fa fa-users fa-fw fa-lg"></i> Joueurs\n </a>\n <a mat-list-item routerLink="[\'adminsList\']">\n <i class="fa fa-user fa-fw fa-lg"></i> Admins\n </a>\n <a mat-list-item routerLinkActive="active" routerLink="[\'gamesList\']">\n <i class="fa fa-futbol-o fa-fw fa-lg"></i> Matchs\n </a>\n <a mat-list-item routerLinkActive="active" routerLink="[\'playgroundsList\']">\n <i class="fa fa-cubes fa-fw fa-lg"></i> Terrains\n </a>\n <a mat-list-item routerLinkActive="active" routerLink="[\'complexesList\']">\n <i class="fa fa-cube fa-fw fa-lg"></i> Complexes\n </a>\n <a mat-list-item routerLinkActive="active" routerLink="[\'devicesList\']">\n <i class="fa fa fa-share-alt fa-fw fa-lg"></i> Capteurs\n </a>\n <a mat-list-item routerLinkActive="active" routerLink="[\'experimental\', \'playgrounds\']">\n <i class="fa fa fa-share-alt fa-fw fa-lg"></i> Business\n </a>\n <a mat-list-item routerLinkActive="active" routerLink="[\'experimental\', \'devices\']">\n <i class="fa fa fa-share-alt fa-fw fa-lg"></i> Technique\n </a>\n </mat-nav-list>\n <mat-nav-list class="account">\n <button mat-button (click)="logout()"><i class="fa fa-sign-out"></i> D\xc3\xa9connexion</button>\n </mat-nav-list>\n\n </mat-sidenav>\n <div class="main mat-typography">\n <!-- primary content -->\n <router-outlet ></router-outlet>\n </div>\n</mat-sidenav-container>\nRun Code Online (Sandbox Code Playgroud)\n\n最后,错误:
\n\nFailed: Template parse errors:\n\'mat-nav-list\' is not a known element:\n1. If \'mat-nav-list\' is an Angular component, then verify that it is part of this module.\n2. If \'mat-nav-list\' is a Web Component then add \'CUSTOM_ELEMENTS_SCHEMA\' to the \'@NgModule.schemas\' of this component to suppress this message. ("\n </div>\n\n [ERROR ->]<mat-nav-list>\n <a mat-list-item routerLinkActive="active" routerLink="[\'usersList\']">\n "): ng:///DynamicTestModule/AppComponent.html@10:4\nRun Code Online (Sandbox Code Playgroud)\n\n所以,正如您所看到的,我已经尝试过这些解决方案:
\n\n\n\n等等。
\n\n我只在单元测试时出现这个问题,网站运行正常。
\n测试需要您手动导入模块。例如,它允许在您需要时加载“模型服务”而不是真实的服务。
您将在此处找到相应的文档,并在同一文档页面上找到相关的主题。
因此,您必须在测试文件(在您的describe项目内)中重新导入所需的模块,例如:
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ /* Your component */ ],
imports: [
/* Here, import your Angular material modules */
],
providers: [
/* Here, use custom or usual providers for your injected services */
]
})
.compileComponents();
}));
Run Code Online (Sandbox Code Playgroud)