业力测试:无法读取未定义的抛出的属性'eventType'

时间:2019-03-10 08:58:53

标签: angular unit-testing karma-jasmine

在Karma(Angular 7)绊脚石的基础上建立单元测试的基础。

<testcase name="HeaderComponent should create" time="0.4" classname="HeaderComponent"> <failure type=""> Uncaught TypeError: Cannot read property 'eventType' of undefined thrown

此特定属性存在于queryObject上,可在我的秋田状态管理器中使用,但是在HeaderComponent中不可用。也没有对秋田商店,queryObject或HeaderComponent中任何内容的引用。

这怎么可能是个问题?

组件:

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.scss']
})
export class HeaderComponent implements OnInit {
  menuHidden = true;

  constructor(
    private router: Router,
    private i18nService: I18nService,
    public authenticationService: AuthenticationService
  ) {}

  ngOnInit() {}

  toggleMenu() {
    this.menuHidden = !this.menuHidden;
  }

  setLanguage(language: string) {
    this.i18nService.language = language;
  }

  logout() {
    this.authenticationService.logout().subscribe(() => this.router.navigate(['/login']));
  }

  get currentLanguage(): string {
    return this.i18nService.language;
  }

  get languages(): string[] {
    return this.i18nService.supportedLanguages;
  }

  get username(): string | null {
    const credentials = this.authenticationService.credentials;
    return credentials ? credentials.username : null;
  }
}

规格:

describe('HeaderComponent', () => {
  let component: HeaderComponent;
  let fixture: ComponentFixture<HeaderComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [RouterTestingModule, NgbModule, TranslateModule.forRoot()],
      declarations: [HeaderComponent],
      providers: [{ provide: AuthenticationService, useClass: MockAuthenticationService }, I18nService]
    }).compileComponents();
  }));

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

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

MockAuthenticationService

export class MockAuthenticationService {
  credentials: Credentials | null = {
    username: 'test',
    token: '123'
  };

  login(context: LoginContext): Observable<Credentials> {
    return of({
      username: context.username,
      token: '123456'
    });
  }

  logout(): Observable<boolean> {
    this.credentials = null;
    return of(true);
  }

  isAuthenticated(): boolean {
    return !!this.credentials;
  }

  isAuthenticatedAdmin(): boolean {
    return true; // this.genericStateModel.isAdmin;
  }
}

模板

  <header>
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
      <a class="navbar-brand" href="/" translate>APP_NAME</a>
      <button class="navbar-toggler" type="button" aria-controls="navbar-menu"
              aria-label="Toggle navigation" (click)="toggleMenu()" [attr.aria-expanded]="!menuHidden">
        <span class="navbar-toggler-icon"></span>
      </button>
      <div id="navbar-menu" class="collapse navbar-collapse float-xs-none" [ngbCollapse]="menuHidden">
        <div class="navbar-nav">
          <a class="nav-item nav-link text-uppercase" routerLink="/herd" routerLinkActive="active">
            <i class="fas fa-home"></i>
            <span translate>herd</span>
          </a>
          <a *ngIf="authenticationService.isAuthenticated() && authenticationService.isAuthenticatedAdmin()" class="nav-item nav-link text-uppercase" routerLink="/stock" routerLinkActive="active">
            <i class="fas fa-warehouse"></i>
            <span translate>stock</span>
          </a>
          <a *ngIf="authenticationService.isAuthenticated() && authenticationService.isAuthenticatedAdmin()" class="nav-item nav-link text-uppercase" routerLink="/orders" routerLinkActive="active">
            <i class="fas fa-money-check-alt"></i>
            <span translate>orders</span>
          </a>
        </div>
        <div class="navbar-nav ml-auto">
          <div class="nav-item" ngbDropdown placement="bottom-right">
            <a id="user-dropdown" class="nav-link" ngbDropdownToggle>
              <i class="fas fa-user-circle"></i>
            </a>
            <div ngbDropdownMenu aria-labelledby="user-dropdown">
              <h6 class="dropdown-header">
                <span translate>logged in as</span> <b>{{username}}</b></h6>
              <div class="dropdown-divider"></div>
              <button class="dropdown-item" (click)="logout()" translate>logout</button>
            </div>
          </div>
        </div>
      </div>
    </nav>
  </header>

0 个答案:

没有答案