捕获TypeError:测试组件时无法读取抛出的null的属性“名称”

时间:2019-10-07 14:43:44

标签: angular jasmine karma-jasmine

因此,我尝试测试此组件及其简单组件,以从可观察对象获取值并将其显示在屏幕上。由于某些原因,当我尝试对其进行测试时,它会引发Uncaught TypeError: Cannot read property 'name' of null thrown错误。

除非我误解了错误,否则我正在初始化userProfile变量,因此该变量应该存在。我该怎么做才能通过?

这是组件文件:

import { Component, OnInit } from '@angular/core';
import { environment } from '../../../../environments/environment';
import { AuthService } from 'src/app/auth/auth.service';

@Component({
  selector: 'user-dropdown',
  templateUrl: './user-dropdown.component.html',
  styleUrls: ['./user-dropdown.component.scss']
})
export class UserDropdownComponent implements OnInit {

  ENV = environment;
  userProfile: Object = {};

  constructor(
    private authService: AuthService
  ) { }

  ngOnInit() {
    this.authService.getUserProfile().subscribe(response => {
      this.userProfile = response.profile;
    }, err => { console.log(err); });
  }

  logout(): void {
    this.authService.logout();
  }
}

这是规格文件:

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { UserDropdownComponent } from './user-dropdown.component';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { FilterPipe } from '../../filters/filter.pipe';
import { AuthService } from 'src/app/auth/auth.service';
import { HttpClient, HttpHandler } from '@angular/common/http';
import { CookieService } from 'ngx-cookie-service';
import { Router } from '@angular/router';
import { of } from 'rxjs';

describe('UserDropdownComponent', () => {
  let component: UserDropdownComponent;
  let fixture: ComponentFixture<UserDropdownComponent>;
  let authServiceStub: any;

  beforeEach(async(() => {
    authServiceStub = {
      getUserProfile: () => of({ profile: {} })
    };

    TestBed.configureTestingModule({
      declarations: [
        UserDropdownComponent,
        FilterPipe
      ],
      schemas: [ NO_ERRORS_SCHEMA ],
      imports: [
        NgbModule,
      ],
      providers: [
        {
          provide: AuthService,
          useValue: authServiceStub
        },
        HttpClient,
        HttpHandler,
        CookieService,
        {
          provide: Router,
          useClass: class { navigate = jasmine.createSpy('navigate'); }
        }
      ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(UserDropdownComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

,这里是HTML引用userProfile.name的地方:

<li *ngIf="userProfile" class="nav-item" ngbDropdown #userDropdown="ngbDropdown" display="dynamic" placement="bottom-right">
  <a class="nav-link" role="button" id="userDropdown" ngbDropdownToggle>
    <i class="fas fa-user-circle"></i>
    {{ userProfile.name }}
    <div ngbDropdownMenu aria-labelledby="userDropdown" class="dropdown-menu">
      <a class="dropdown-item">Profile</a>
      <a class="dropdown-item">My Downloads</a>
      <div class="dropdown-divider"></div>
      <a class="dropdown-item" (click)="logout()">Logout</a>
    </div>
  </a>
</li>

1 个答案:

答案 0 :(得分:0)

我认为这是正确的行为。您已将属性“ userProfile”初始化为空对象,因此,在ngIf中,由于空对象为真值,因此它将为true。如果您不希望html块呈现,除非您定义了userProfile,否则应将其初始化为undefined或null。