本文介绍了无法等待在角度/茉莉单元测试中完成DOM呈现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个通过VegaEmbed(https://github.com/vega/vega-embed)构建的角度饼图组件,它使用Vega和D3作为底层图形依赖项。它通过提供标题和一些(键、值)对进行呈现。我隔离了该组件,并修改main.ts以在Stackblitz之外运行Jasmine,以便与您共享。在此测试中,我检查饼图是否确实为值"30%"|"70%"和图例"合并的CEO/董事长"|"单独的CEO/董事长"呈现了SVG<text>标记。然而,它们似乎运行得太早了,VegaEmbed+Vega+D3仍在忙于构建SVG。(我只是通过Chrome dev工具查看DOM来推断要测试的内容)。

https://stackblitz.com/edit/angular-d3-pie-chart-unit-test

我尝试了一系列操作:asyncFakeAsync+tickjasmine.clock、更改角度组件中的承诺逻辑,等等……fixture.whenStable使我更接近了一步,但是texts声明的第50行仍未定义。

我不知道Vega、VegaEmbed和D3的内部是如何工作的。如果这些库没有使用承诺,而是相当老式的回调,那么ANGLE的区域可能无法在async

中等待足够长的时间让我有点困惑的是console.log(texts);最终在控制台中显示了一个包含4个文本SVG元素的集合。但console.log(texts.length);显示0!

  1. 怎么会这样?
  2. 如何让我的测试代码等到D3绘制完SVG之后才运行expect语句?

推荐答案

这是一个很好的问题,我遇到了与Ag-Grid类似的问题,在执行断言之前必须等待呈现或其回调完成,并且没有像您提到的fakeAsyncasync/done等的好方法。至少我没有发现任何好方法。

我发现的一种方法是制作一个效用函数,如下所示:

import { interval } from 'rxjs';
.....
export const waitUntil = async (untilTruthy: Function): Promise<boolean> => {
  while (!untilTruthy()) {
    // older API
    // await interval(25).pipe(take(1)).toPromise();
    // newer API
    await firstValueFrom(interval(25));
  }
  return Promise.resolve(true);
};

waitUntil将每25ms循环一次,直到提供的回调函数为true。时间长短由您决定。

因此,在您的测试中,您可以执行如下操作:

it('should render the chart', async () => {
  // make your arrangements
  // do your action
  fixture.detectChanges();
  // wait for promises to resolve (optional)
  await fixture.whenStable();
  await waitUntil(() => /* put a condition here that will resolve to a truthy value
  at a later time where the rest of the assertions rely on
  it such as the graph being present with its labels*/);
  // the rest of your assertions of what should be there what should not
});
您提到setTimeout使用值0。这是可行的,因为我们将setTimeout中的内容放在调用堆栈队列的末尾,因为它是异步运行的。这样做仍然不错,但我喜欢waitUntil方法测试的阅读方式。

这篇关于无法等待在角度/茉莉单元测试中完成DOM呈现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-02 21:08