- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我目前正在处理遗留的 Angular 5 代码,该代码在使用 Angular CLI 生成组件时除了默认单元测试外没有任何单元测试。
该项目正在使用 Angular Material 5 RC0,单元测试似乎没有考虑我的模块的依赖性。
app.module.ts :
@NgModule({
declarations: [
AppComponent,
/* My module components... */
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
ReactiveFormsModule,
BrowserAnimationsModule,
routing,
DialogsModule,
SharedModule ,
MaterialModule,
MatListModule, // It's the module that should be needed
MatSidenavModule,
ToastrModule.forRoot({
timeOut: 5000,
positionClass: 'toast-bottom-right',
preventDuplicates: true
}),
HttpClientModule,
TableFactoryModule
],
providers: [
/* My module services */,
AuthGuard
],
bootstrap: [AppComponent]
})
export class AppModule {
}
app.component.ts:
import { Component, Input, ViewChild } from '@angular/core';
import { Router, RouterModule, ActivatedRoute } from '@angular/router';
import { HttpErrorResponse } from '@angular/common/http';
import { JwtHelperService } from '@auth0/angular-jwt';
import * as _ from 'lodash';
import { Subscription } from 'rxjs/Subscription';
import { ToastrService } from 'ngx-toastr';
import { UsersService } from 'app/services/users.service';
import { ComplexesService } from 'app/services/complexes.service';
import { ActivatedUserService } from 'app/shared/activateduser.service';
import { ActivatedComplexesService } from 'app/shared/activatedcomplexes.service';
import { User } from 'app/user';
import { Complex } from './complex/complex'
import { MatSidenav } from '@angular/material';
import { MatList } from '@angular/material/list'
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app works!';
isConnected = false;
private subscription;
private currentUser: User;
userSubscription: Subscription;
complexesSubscription: Subscription;
@ViewChild(MatSidenav) sidenav: MatSidenav;
constructor(
private usersService: UsersService,
private complexesService: ComplexesService,
private router: Router,
private toastr: ToastrService,
private activatedUser: ActivatedUserService,
private activatedComplexes: ActivatedComplexesService,
){
}
ngOnInit() {
let getToken = this.usersService.isConnected();
if (getToken) {
this.getComplexes();
this.userGetById();
}
else
this.router.navigate(['']);
this.userSubscription = this.activatedUser.activatedUser$
.subscribe(user => {
if(user) {
this.currentUser = user;
this.sidenav.open();
}
});
}
logout(){
this.usersService.logout();
this.isConnected = this.usersService.isConnected();
this.router.navigate(['']);
}
ngOnDestroy() {
this.userSubscription.unsubscribe();
this.complexesSubscription.unsubscribe();
}
private userGetById(){
let token = JSON.parse(localStorage.getItem('futbakCurrentUser'));
let jwtHelperService: JwtHelperService = new JwtHelperService({});
let currentUser = jwtHelperService.decodeToken(token);
this.usersService.getByID(currentUser.id).subscribe(
(res) => {
this.currentUser = res
}, (err: HttpErrorResponse) => {
if (err.error instanceof Error) {
// A client-side or network error occurred. Handle it accordingly.
this.toastr.error("Une erreur est survenue : "+err.error.message , '', { closeButton: true });
} else {
this.toastr.error("Une erreur est survenue code : "+ err.status+", message : "+err.statusText, '', { closeButton: true });
}
},
() => {
if(this.currentUser.role == 'superadmin' || this.currentUser.role == 'complexmanager') {
this.activatedUser._activatedUser$.next(this.currentUser)
}
if(this.currentUser.role == 'superadmin') {
this.router.navigate(['usersList']);
this.getComplexes();
} else if (this.currentUser.role == 'complexmanager') {
this.router.navigate(['admins/'+this.currentUser._id])
} else {
this.toastr.error("Vous n'avez pas les droits pour accèder à l'application.",'',{closeButton :true});
}
});
}
private getComplexes(){
return this.complexesService.get()
.subscribe(
res => {
if(res)
this.activatedComplexes._activatedComplexes$.next(res)
}, (err: HttpErrorResponse) => {
if (err.error instanceof Error) {
this.toastr.error("Une erreur est survenue : "+err.error.message , '', { closeButton: true });
} else {
this.toastr.error("Une erreur est survenue code : "+ err.status+", message : "+err.statusText, '', { closeButton: true });
}
},
() => {
});
}
}
失败的测试:
it('should create the app', async(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app).toBeTruthy();
}));
app.component.html :
<mat-sidenav-container fullscreen >
<mat-sidenav #sidenav mode="side" disableClose>
<!-- sidenav content -->
<div><img src="./assets/logo.png" class="logo" ></div>
<div class="title-app">
<h2>Admin</h2>
</div>
<mat-nav-list>
<a mat-list-item routerLinkActive="active" routerLink="['usersList']">
<!-- <mat-icon fontSet="fa" fontIcon="fa-users" ></mat-icon> -->
<i class="fa fa-users fa-fw fa-lg"></i> Joueurs
</a>
<a mat-list-item routerLink="['adminsList']">
<i class="fa fa-user fa-fw fa-lg"></i> Admins
</a>
<a mat-list-item routerLinkActive="active" routerLink="['gamesList']">
<i class="fa fa-futbol-o fa-fw fa-lg"></i> Matchs
</a>
<a mat-list-item routerLinkActive="active" routerLink="['playgroundsList']">
<i class="fa fa-cubes fa-fw fa-lg"></i> Terrains
</a>
<a mat-list-item routerLinkActive="active" routerLink="['complexesList']">
<i class="fa fa-cube fa-fw fa-lg"></i> Complexes
</a>
<a mat-list-item routerLinkActive="active" routerLink="['devicesList']">
<i class="fa fa fa-share-alt fa-fw fa-lg"></i> Capteurs
</a>
<a mat-list-item routerLinkActive="active" routerLink="['experimental', 'playgrounds']">
<i class="fa fa fa-share-alt fa-fw fa-lg"></i> Business
</a>
<a mat-list-item routerLinkActive="active" routerLink="['experimental', 'devices']">
<i class="fa fa fa-share-alt fa-fw fa-lg"></i> Technique
</a>
</mat-nav-list>
<mat-nav-list class="account">
<button mat-button (click)="logout()"><i class="fa fa-sign-out"></i> Déconnexion</button>
</mat-nav-list>
</mat-sidenav>
<div class="main mat-typography">
<!-- primary content -->
<router-outlet ></router-outlet>
</div>
</mat-sidenav-container>
最后,错误:
Failed: Template parse errors:
'mat-nav-list' is not a known element:
1. If 'mat-nav-list' is an Angular component, then verify that it is part of this module.
2. If 'mat-nav-list' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. ("
</div>
[ERROR ->]<mat-nav-list>
<a mat-list-item routerLinkActive="active" routerLink="['usersList']">
"): ng:///DynamicTestModule/AppComponent.html@10:4
因此,如您所见,我已经尝试过这些解决方案:
等等。
我只是单元测试有这个问题,网站运行正常。
最佳答案
测试需要您手动导入模块。例如,它允许在您需要时加载“模型服务”而不是真实服务。
您会找到相应的文档 here , 以及同一文档页面上的相关主题。
所以你必须在你的测试文件中重新导入所需的模块(在你的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();
}));
关于 Angular 单元测试 : 'mat-nav-list' is not a known element,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56145278/
我已经彻底搜索过,但没有找到直接的答案。 将 opencv 矩阵 (cv::Mat) 作为参数传递给函数,我们传递的是智能指针。我们对函数内部的输入矩阵所做的任何更改也会改变函数范围之外的矩阵。 我读
是否可以有一个垫子分隔线(一条水平线分隔两个垫子选项)? 我试过: Cars Volvo Saab Mercedes Audi
使用的浏览器 - Chrome 67.0.3396.99 我创建了一个 DialogsModule它有一个组件 ConfirmDialog.component.ts使用以下模板 confirm-dia
我正在尝试使用 mat-toolbar 但出现错误: mat-menu.component.html: Responsive Navigation Menu I
我正在创建 angular 7 网络应用程序,并使用一个 mat-select 下拉菜单和一个 mat-paginator。现在我隐藏 mat-select 向下箭头。 Here is the mat
在我的应用程序中,我有一个通过引用接收 cv::Mat 对象的函数。这是函数的声明: void getChains(cv::Mat &img,std::vector &chains,cv::
我使用了独立的 EMA (1.5.0) 和 eclipse 插件(在 eclipse 4.5 中)来分析我的堆转储。 我想查看任何无法访问的对象信息,我已尝试在我的首选项和命令行选项 -keep_un
我是 flex 的新手,我的垫子 table 做得很好。 不幸的是,我的标题没有遵循我的单元格宽度。 这是我的结果的图片。 如您所见,我的标题与我的单元格不对齐。 这是我的 CSS 代码,就像我说我是
我试图在我的 Material 表上使用 mat-sort 和 mat-paginator,但似乎不起作用。 Table 确实获取了 dataSource.data 中的数据,它也显示在 mat-ta
我试图在我的 Material 表上使用 mat-sort 和 mat-paginator,但似乎不起作用。 Table 确实获取了 dataSource.data 中的数据,它也显示在 mat-ta
我想在每个 mat-option 文本上设置悬停样式,我希望文本显示在 mat-option 之外。为了实现这一点,我应用了非常高的 z-index 值,但没有任何改变。我尝试将 z-index 添加
默认情况下 mat-drawer-container/mat-sidenav-container 和 mat-drawer/mat-sidenav 高度基于 mat-drawer-cont
在 mat-card-header 中提供图像头像通过 mat-card-avatar 得到很好的支持. 在许多用例中,我们希望使用图标而不是图像作为卡片的“头像”。 有没有一种简单的方法可以用图标替
我想要一个包含 2 列的网格列表,并且在这些列中我想要 2 个垂直堆叠的复选框。 我看过 this question 这确实有点 工作,但我想知道是否有更简洁的方法解决这个问题,因为我必须使用大量的
更新:stackbliz https://angular-2wqf4b.stackblitz.io 我正在构建一个比较屏幕,我们可以在其中比较两个项目。我试图将这两项显示为两个 mat-cards里
试图模仿 Material guide 的外观,我无法让工具栏的阴影呈现在 mat-sidenav-container 元素之上: 显示工具栏和 sidenav 的页面,但投影不可见: 单独显示工具栏
请注意,分页/排序无法正常工作。分页不显示它显示的元素数量并且排序不起作用,但是如果您删除 html 文件中的行 *ngIf="dataSource?.filteredData.length > 0"
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: Proper stack and heap usage in C++? Heap vs Stack allo
单击每个单选按钮时,我需要为每个垫卡添加背景。背景应仅适用于与单击的垫单选按钮对应的垫卡。
Mat a = (Mat_(3,3) = 2 int dims; //! the number of rows and columns or (-1, -1) when the arr
我是一名优秀的程序员,十分优秀!