订阅了构造函数中订阅服务主题的Jasmine单元测试角度组件给出了无法读取未定义的订阅属性

时间:2018-07-19 17:42:47

标签: angular unit-testing jasmine rxjs

我正在尝试为下面的组件编写测试。

^                 Ok: No text before here
/path/foo         "/path/foo"
(?:/[^/]+)*       "/a/b/script"
(?<!/script)      Fail: Text before here is "/script"
/                 "/"
[^/]*             "file"
$                 Ok: No text after here

但是,当我编写测试时,会出现此错误

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

import { LoginService } from '../../services/login.service';

@Component({
  selector: 'app-banner',
  templateUrl: './banner.component.html',
  styleUrls: ['./banner.component.css']
})
export class BannerComponent implements OnInit {

  isLoggedIn = false;
  user: User = new User('');

  constructor(
    private loginService: LoginService,
    private router: Router
  ) {
    this.loginService.userWatcher.subscribe(res => {
      this.isLoggedIn = true;
      this.user.oun = res;
    });
  }
...

}

这是规格文件:

TypeError: Cannot read property 'subscribe' of undefined

以下是我的登录服务间谍文件:

import { LoginServiceSpy } from '../../services/mock/login.service.spy.spec';
describe('BannerComponent', () => {
  let component: BannerComponent;
  let fixture: ComponentFixture<BannerComponent>;
  const loginService = LoginServiceSpy;
  const user = 'testuser';

  beforeEach(async(() => {

    TestBed.configureTestingModule({
      declarations: [
        BannerComponent,
        MockComponent(SpinnerComponent)
      ],
      imports: [
        FormsModule,
        NgbModule.forRoot(),
        RouterTestingModule
      ],
      providers: [
        { provide: LoginService, useValue: loginService }
      ]
    }).compileComponents();
  }));

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

  describe('Unit Tests', () => {

    beforeEach(() => {
      localStorage.setItem('currentUser', user);
      loginService.callNextUserWatcher.and.returnValue(asyncData('test'));
    });
...

在banner.component.spec.ts中,我尝试过尝试以下各项:

import { createSpyFromClass, Spy } from 'jasmine-auto-spies';
import { LoginService } from '../login.service';

export const LoginServiceSpy: Spy<LoginService> = createSpyFromClass(LoginService);

我从茉莉花那里得到了答复:     无法读取属性和未定义的

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:-1)

这可能是因为外部fixture.detectChanges()上的beforeEach()首先运行并将加载您的组件。当时您的spy尚未创建,因此您遇到了该错误。

将间谍移动到外部beforeEach()

beforeEach(() => {
    fixture = TestBed.createComponent(BannerComponent);
    component = fixture.componentInstance;
    loginService.callNextUserWatcher.and.returnValue(asyncData('test')); // spy created before detect change
    fixture.detectChanges();
  });

或者不要从外部fixture.detectChanges();运行beforeEach()

 beforeEach(() => {
    fixture = TestBed.createComponent(BannerComponent);
    component = fixture.componentInstance;
   // fixture.detectChanges();  -- remove this line
  });

首先detectChange应该在初始化所有应用程序数据之后发生。