如何在 ngOninit 中为订阅块编写 Jasmine 测试用例并传递一些虚拟数据?

How to write Jasmine Test case for a subscribe block in ngOninit and pass some dummy data?

我在 Angular 7 中第一次尝试 Jasmine 测试用例。我有一个 observable,它使用服务文件中的 next() 发出数据。组件订阅可观察对象并使用数据。这是 ngOnInit

中的代码
ngOnInit() {
    this.loading = true;

    this.subscribe(this.advDirectService.directive$, data => {          
        this.directives = data;
        this.loading = false;
    });
    this.advDirectService.loadDirective(); }

我预计会调用 loadDirective。但是当我尝试期望 this.directives 时,它总是说 NULL。我的组件扩展了一个 BaseComponent。请帮助我学习如何为订阅块中的代码编写测试。

您需要将服务和组件的测试分开。单元测试意味着尽可能地隔离。

与其测试服务是否在组件中工作,不如使用模拟数据,您可以像这样传递它并只测试组件功能:

it('should test something for the component', () => {
  component.directives = mockData;

  // run a function that depends on the data and expect a return result
})

另一方面,您需要测试服务及其异步调用,您应该在服务中执行此操作。spec.ts 文件:

it('should test something in the service', (done) => {
  this.directive$.subscribe(data => {
    expect(data) ... something
    done();
  })
})

请注意,我们将完成参数传递给回调 - 这表明异步测试已完成 - 否则测试将因超时错误而失败。

不过我应该警告你,异步测试可能很复杂:如果你希望第一个发射总是空的,你可能需要在你的订阅之前管道(skip(1))。

还有其他测试可观察对象的方法,例如大理石测试 - 但我个人还没有深入研究。

应该是这样的:

let dummy_data = "Some dummy data to be returned by service";
const spyOnInit = spyOn(component, "ngOnInit").and.callThrough();
    advDirectService = TestBed.get(<Your Service Name>);
    const spyData = spyOn(advDirectService, "directive$")
      .and.returnValue(Observable.of(dummy_data));
    advDirectService.directive$().subscribe(
      success => {
        expect(success).toEqual(advDirectService);
      }
      , (error) => {
        expect(error).toBeTruthy();
      });

    component.ngOnInit();
    expect(component.ngOnInit).toHaveBeenCalled(); //write your expect statement here
    spyData.calls.reset();
    spyOnInit.calls.reset();