簡體   English   中英

TypeError: navbarUserInfoComponent[0] 在 Jasmine 測試中未定義

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM