TypeError: navbarUserInfoComponent[0] is undefined in Jasmine test
TypeError: navbarUserInfoComponent[0] is undefined in Jasmine test
我目前正在编写 jasmine 测试用例来测试注销菜单组件是否正常工作。
这是我的 TS 文件。
import { Component, OnInit } from '@angular/core';
import { Observable, of } from 'rxjs';
import { MatDialog } from '@angular/material/dialog'
import { Router } from '@angular/router';
import { RecursiveAstVisitor } from '@angular/compiler/src/output/output_ast';
//import { faChalkboard, faExclamationTriangle, IconDefinition } from '@fortawesome/free-solid-svg-icons';
import { take } from 'rxjs/operators';
import { AuthenticationService } from 'src/app/services/shared/authentication.service';
import { LoginService } from 'src/app/services/shared/login.service';
@Component({
selector: 'app-navbar-user-info',
templateUrl: './navbar-user-info.component.html',
styleUrls: ['./navbar-user-info.component.scss']
})
export class NavbarUserInfoComponent implements OnInit {
// notificationIcon: IconDefinition;
// //RID Icon
// faExclamationTriangle = faExclamationTriangle;
// //Whiteboard Icon
// faChalkboard = faChalkboard;
totalNotifications = 0;
user;
employee;
expanded: any[][] = new Array();
interval;
pageRoute = '/dynamic';
tooltipPosition = "above"
constructor(
public authenticationService: AuthenticationService,
private loginService: LoginService,
//private userService: UserAPI,
private dialog: MatDialog,
private router: Router
) { }
ngOnInit() {
console.log("Initializing: header-user-info.component.ts")
console.log(this.authenticationService.getEmployeeId());
console.log(this.authenticationService.getUserName());
this.user=this.authenticationService.getUserName();
}
logout() {
this.loginService.logout();
}
}
这是 html 文件:
<div class="nav-div" *ngIf="authenticationService.isLoggedIn() | async as loggedIn" fxLayout="row" fxLayoutAlign="start center"
fxLayoutGap="12px">
<div *ngIf="user">
<mat-menu #userMenu="matMenu">
<div class="user-profile-details">User: {{user}}</div>
<!-- <div class="user-profile-details">Role: {{user?.role?.roleName}}</div> -->
<!--<div class="user-profile-details">Company: {{user?.companyNm}}</div> -->
<mat-divider></mat-divider>
<button mat-menu-item (click)="logout()">Logout</button>
</mat-menu>
<button mat-button [matMenuTriggerFor]="userMenu" class="no-hover">
<!-- <mat-icon class="material-icons">account_circle</mat-icon> -->
<i class="fas fa-user-circle fa-lg material-icons"></i>
</button>
</div>
</div>
这是基于我参加的 Jasmine 测试课程的规范文件。
(这是规范文件中当前的内容)
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { NavbarUserInfoComponent } from './navbar-user-info.component';
import { AuthenticationService } from 'src/app/services/shared/authentication.service';
import { LoginService } from 'src/app/services/shared/login.service';
import { MatDialog } from '@angular/material/dialog';
import { Router } from '@angular/router';
import { By } from "@angular/platform-browser";
import { MatMenuItem } from '@angular/material/menu';
import { HttpClientTestingModule, HttpTestingController} from "@angular/common/http/testing";
import { of } from 'rxjs';
export class mockAuthentication{
getUserInfo(){
return "1";
};
getUserRole(){
return "admin";
};
getUserName(){
return "Test User";
};
isLoggedIn(){
return true;
};
};
describe('NavbarUserInfoComponent', () => {
let component: NavbarUserInfoComponent;
let fixture: ComponentFixture<NavbarUserInfoComponent>;
let mockLoginService, mockMatDialog, mockRouter; //, mockAuthentication;
let USER;
beforeEach(async(() => {
USER = [
{id:1, name:'Test User', role: 'admin'}
]
//mockAuthentication = jasmine.createSpyObj(['getUserInfo','getUserRole','getUserName','isLoggedIn']);
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
declarations: [ NavbarUserInfoComponent ],
providers: [
{provide: AuthenticationService, useValue: mockAuthentication},
{provide: LoginService, useValue: mockLoginService},
{provide: MatDialog, useValue: mockMatDialog},
{provide: Router, useValue: mockRouter}
],
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(NavbarUserInfoComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should test a click of the logout button', () => {
spyOn(fixture.componentInstance, 'logout').and.callThrough();
fixture.detectChanges();
const link = fixture.nativeElement.querySelector('#btn-Logout');
link.click();
expect(fixture.componentInstance.logout).toHaveBeenCalled();
})
});
我的问题是当它运行时我得到了这个结果。
(我已更新以显示当前错误消息)
我的问题是,为什么说 'navbarUserInfoComponent[0]' 未定义?
如果我取消 [0],我会收到一条消息,指出 'triggerEventHandler' 未定义。
在这种情况下我做错了什么?
您没有正确捕捉 HTML 元素。尝试输入 id
以轻松获取元素
<button id="logout-btn" mat-menu-item (click)="logout()">Logout</button>
在 spec
文件中:
it('should test a click of the logout button', () => {
spyOn(component,'logout').and.callThrough();
fixture.detectChanges();
const btn = fixture.nativeElement.querySelector('#logout-btn');
btn.click();
expect(component.logout).toHaveBeenCalled();
)}
更新:
通过创建模拟来定义 user
class MockAuthenticationService{
getUserName(){
return "hero"
}
// and other methods as well
}
并在 TestBed
中尝试:
// ......
providers: [
{provide: AuthenticationService, useClass: MockAuthenticationService},
我目前正在编写 jasmine 测试用例来测试注销菜单组件是否正常工作。
这是我的 TS 文件。
import { Component, OnInit } from '@angular/core';
import { Observable, of } from 'rxjs';
import { MatDialog } from '@angular/material/dialog'
import { Router } from '@angular/router';
import { RecursiveAstVisitor } from '@angular/compiler/src/output/output_ast';
//import { faChalkboard, faExclamationTriangle, IconDefinition } from '@fortawesome/free-solid-svg-icons';
import { take } from 'rxjs/operators';
import { AuthenticationService } from 'src/app/services/shared/authentication.service';
import { LoginService } from 'src/app/services/shared/login.service';
@Component({
selector: 'app-navbar-user-info',
templateUrl: './navbar-user-info.component.html',
styleUrls: ['./navbar-user-info.component.scss']
})
export class NavbarUserInfoComponent implements OnInit {
// notificationIcon: IconDefinition;
// //RID Icon
// faExclamationTriangle = faExclamationTriangle;
// //Whiteboard Icon
// faChalkboard = faChalkboard;
totalNotifications = 0;
user;
employee;
expanded: any[][] = new Array();
interval;
pageRoute = '/dynamic';
tooltipPosition = "above"
constructor(
public authenticationService: AuthenticationService,
private loginService: LoginService,
//private userService: UserAPI,
private dialog: MatDialog,
private router: Router
) { }
ngOnInit() {
console.log("Initializing: header-user-info.component.ts")
console.log(this.authenticationService.getEmployeeId());
console.log(this.authenticationService.getUserName());
this.user=this.authenticationService.getUserName();
}
logout() {
this.loginService.logout();
}
}
这是 html 文件:
<div class="nav-div" *ngIf="authenticationService.isLoggedIn() | async as loggedIn" fxLayout="row" fxLayoutAlign="start center"
fxLayoutGap="12px">
<div *ngIf="user">
<mat-menu #userMenu="matMenu">
<div class="user-profile-details">User: {{user}}</div>
<!-- <div class="user-profile-details">Role: {{user?.role?.roleName}}</div> -->
<!--<div class="user-profile-details">Company: {{user?.companyNm}}</div> -->
<mat-divider></mat-divider>
<button mat-menu-item (click)="logout()">Logout</button>
</mat-menu>
<button mat-button [matMenuTriggerFor]="userMenu" class="no-hover">
<!-- <mat-icon class="material-icons">account_circle</mat-icon> -->
<i class="fas fa-user-circle fa-lg material-icons"></i>
</button>
</div>
</div>
这是基于我参加的 Jasmine 测试课程的规范文件。 (这是规范文件中当前的内容)
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { NavbarUserInfoComponent } from './navbar-user-info.component';
import { AuthenticationService } from 'src/app/services/shared/authentication.service';
import { LoginService } from 'src/app/services/shared/login.service';
import { MatDialog } from '@angular/material/dialog';
import { Router } from '@angular/router';
import { By } from "@angular/platform-browser";
import { MatMenuItem } from '@angular/material/menu';
import { HttpClientTestingModule, HttpTestingController} from "@angular/common/http/testing";
import { of } from 'rxjs';
export class mockAuthentication{
getUserInfo(){
return "1";
};
getUserRole(){
return "admin";
};
getUserName(){
return "Test User";
};
isLoggedIn(){
return true;
};
};
describe('NavbarUserInfoComponent', () => {
let component: NavbarUserInfoComponent;
let fixture: ComponentFixture<NavbarUserInfoComponent>;
let mockLoginService, mockMatDialog, mockRouter; //, mockAuthentication;
let USER;
beforeEach(async(() => {
USER = [
{id:1, name:'Test User', role: 'admin'}
]
//mockAuthentication = jasmine.createSpyObj(['getUserInfo','getUserRole','getUserName','isLoggedIn']);
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
declarations: [ NavbarUserInfoComponent ],
providers: [
{provide: AuthenticationService, useValue: mockAuthentication},
{provide: LoginService, useValue: mockLoginService},
{provide: MatDialog, useValue: mockMatDialog},
{provide: Router, useValue: mockRouter}
],
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(NavbarUserInfoComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should test a click of the logout button', () => {
spyOn(fixture.componentInstance, 'logout').and.callThrough();
fixture.detectChanges();
const link = fixture.nativeElement.querySelector('#btn-Logout');
link.click();
expect(fixture.componentInstance.logout).toHaveBeenCalled();
})
});
我的问题是当它运行时我得到了这个结果。 (我已更新以显示当前错误消息)
我的问题是,为什么说 'navbarUserInfoComponent[0]' 未定义?
如果我取消 [0],我会收到一条消息,指出 'triggerEventHandler' 未定义。
在这种情况下我做错了什么?
您没有正确捕捉 HTML 元素。尝试输入 id
以轻松获取元素
<button id="logout-btn" mat-menu-item (click)="logout()">Logout</button>
在 spec
文件中:
it('should test a click of the logout button', () => {
spyOn(component,'logout').and.callThrough();
fixture.detectChanges();
const btn = fixture.nativeElement.querySelector('#logout-btn');
btn.click();
expect(component.logout).toHaveBeenCalled();
)}
更新:
通过创建模拟来定义 user
class MockAuthenticationService{
getUserName(){
return "hero"
}
// and other methods as well
}
并在 TestBed
中尝试:
// ......
providers: [
{provide: AuthenticationService, useClass: MockAuthenticationService},