【问题标题】:Angular, Service Unit Test. Waiting for observable valueAngular,服务单元测试。等待可观察值
【发布时间】:2019-09-08 06:05:17
【问题描述】:

我正在尝试对 BehaviorSubject 执行简单的单元测试。 它看起来像这样:

   fit('pageChange', fakeAsync(() => {
        spyOn(pagintationService, 'pageChange');

        pagintationService.pageChange(3);

        expect(pagintationService.pageChange).toHaveBeenCalledWith(3);

        tick(100);

        pagintationService.page$.subscribe(pageNum => {
            console.log(pageNum)
        })
    }))

当我登录 susbscribe() 时,我希望这个值是 3。那是因为实现看起来像这样:

  pageChange(page: number) {
        this.paginationPageSource.next(page);
    }

在哪里

firstPage = 0;

    private paginationPageSource = new BehaviorSubject<number>(this.firstPage);
    page$ = this.paginationPageSource.asObservable();

这是为什么呢?我也尝试过使用 flushMicrotasks() 但没有任何反应。

更新

fit('pageChange', fakeAsync(() => {
        let pageNum = 3;

        spyOn(pagintationService, 'pageChange').and.callThrough();

        pagintationService.pageChange(pageNum);

        pagintationService.page$.subscribe(num =>
            expect(num).toBe(pageNum))

        expect(pagintationService.pageChange).toHaveBeenCalledWith(3);
    }))

【问题讨论】:

  • 为什么是什么?有什么问题?你已经说出了你的期望。你还没有告诉你观察到的东西。
  • 我想在 paginationPageSource.next(page); 时模拟动作将发出数字(此处为 3),然后检查 page$ 是否包含此值。
  • 好的。但这并不能告诉我们问题是什么。但无论如何:你明白什么是间谍吗?当您拨打spyOn(pagintationService, 'pageChange'); 时会发生什么?为什么要监视要测试的方法?

标签: angular unit-testing rxjs jasmine karma-jasmine


【解决方案1】:

啊,您希望 console.log 触发并打印出 3。现在它不会,因为您在传递了一个 3 之后会听取您的 observable。在这种情况下,您需要在进行更改之前听取更改更改,然后它将按照您的预期运行。

以下内容可能会按您的预期工作。

it('pageChange', () => {
  const pagintationService: TestService = TestBed.get(TestService);
  let pageNum: number;

  spyOn(pagintationService, 'pageChange').and.callThrough();

  pagintationService.page$.subscribe(num => {
    console.log(`subscribe sees a ${num}`);
    pageNum = num;
  });

  pagintationService.pageChange(3);

  expect(pagintationService.pageChange).toHaveBeenCalledWith(3);
  expect(pageNum).toBe(3);
});

这会写出来

LOG: 'subscribe sees a 0' // since behavior subject sends current value
LOG: 'subscribe sees a 3'

还请注意,我删除了 fakeAsynctick,因为这两者都不是必要的。您只需要在需要经过时间时使用tick,例如去抖动或setTimeout

【讨论】:

    猜你喜欢
    • 2019-03-25
    • 2018-12-11
    • 1970-01-01
    • 2021-04-11
    • 2017-05-12
    • 1970-01-01
    • 2017-10-12
    • 2018-01-03
    • 2020-09-21
    相关资源
    最近更新 更多