角度单元测试:“mat-nav-list”不是已知元素

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}\n
Run Code Online (Sandbox Code Playgroud)\n\n

应用程序组件.ts:

\n\n
import { 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 }\n
Run Code Online (Sandbox Code Playgroud)\n\n

失败的测试:

\n\n
it(\'should create the app\', async(() => {\n    const fixture = TestBed.createComponent(AppComponent);\n    const app = fixture.debugElement.componentInstance;\n    expect(app).toBeTruthy();\n  }));\n
Run 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>\n
Run Code Online (Sandbox Code Playgroud)\n\n

最后,错误:

\n\n
Failed: 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\n
Run Code Online (Sandbox Code Playgroud)\n\n

所以,正如您所看到的,我已经尝试过这些解决方案:

\n\n\n\n

等等。

\n\n

我只在单元测试时出现这个问题,网站运行正常。

\n

Mic*_*Mic 6

测试需要您手动导入模块。例如,它允许在您需要时加载“模型服务”而不是真实的服务。

您将在此处找到相应的文档,并在同一文档页面上找到相关的主题。

因此,您必须在测试文件(在您的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)