[英]AngularJS Jasmine test: TypeError: 'undefined' is not an object
[英]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 測試課程的規范文件。 (這是目前在 Spec 文件中的內容)
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},
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.