单元测试中的角度“无法读取未定义的属性'subscribe'”

时间:2020-01-14 19:18:03

标签: angular typescript unit-testing mocking observable

我正在使用Jest对我的Angular应用进行单元测试,并且不断收到此错误 TypeError: Cannot read property 'subscribe' of undefined 在线解决方案似乎没有任何意义或无法正常工作。这是一些代码:

page-view.component.ts

  @Input() gotPlot!: Observable<void>;
  ...
  ngOnInit() {
    this.initialiseColumnDefs();
    this.gotPlot.subscribe((response) => { //ERROR is occurring on this line
      this.gotPlotValues(response);
    });
  }

page.component.ts

@Component({
  selector: 'page',
  template: `
    <page-view
      [gotPlot]="gotPlotSubject.asObservable()"
    >
    </page-view>
  `,
})

export class PageComponent implements OnInit {
  ...
  public gotPlotSubject: Subject<void> = new Subject<void>();
  ...

  async get_plot(arr: any): Promise<any[]> {

    //This function calls a service and gets 'plotValues'
    (await this.service.get_plot(input)).subscribe((data: any) => {

      //plotValues is set to values gotten from the service here     

      this.gotPlotSubject.next(plotValues);
    });
  }
}

page-view.component.spec.ts

@Component({
  selector: 'page',
  template: `
    <page-view *ngIf="gotPlotSubject.asObservable()" [gotPlot]="gotPlotSubject.asObservable()">
    </page-view>
  `,
})
class PageMock {
  public gotPlotSubject: Subject<void> = new Subject<void>();
  constructor() {}
  ngOnInit() {
    let plotValues: any = [];
    plotValues[0] = 1;
    plotValues[1] = [1, 2, 3];
    plotValues[2] = [2, 3, 4];
    this.gotPlotSubject.next(plotValues);
  }
}

describe('ViewComponent', () => {
  let spectator: Spectator<ViewComponent>;

  const createComponent = createComponentFactory({
    component: ViewComponent,
    declarations: [
      ViewComponent,
      PageMock,
    ],
    imports: [TranslateModule.forRoot(), MaterialModule, AgGridModule, FormsModule],
    providers: [HttpClient, HttpHandler, NGXLogger, NGXMapperService, HttpBackend, NGXLoggerHttpService, LoggerConfig],
    schemas: [NO_ERRORS_SCHEMA],
  });

  beforeEach(() => {
    spectator = createComponent();
  });

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

我的PageMock错误吗?我如何正确模拟可观察者/订阅者?是否有一种更简单的方法,而无需使用可观察变量或订阅? Subscribe和Observables似乎使单元测试的方式比应有的痛苦更多。

1 个答案:

答案 0 :(得分:1)

尝试做

@Component({
  selector: 'page',
  template: `
    <page-view *ngIf="gotPlotSubject.asObservable() | async" [gotPlot]="gotPlotSubject.asObservable()">
    </page-view>
  `,
})

检出async上的*ngIf管道。 *ngIf上可观察值的未包装值将始终是真实的。我什至会摆脱asObservable()。我认为它们不是必需的,但您可以尝试一下。

您是对的,使用RxJS进行测试可能很棘手。