本文介绍了无法等待在角度/茉莉单元测试中完成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
我尝试了一系列操作:async
、FakeAsync
+tick
、jasmine.clock
、更改角度组件中的承诺逻辑,等等……fixture.whenStable
使我更接近了一步,但是texts
声明的第50行仍未定义。我不知道Vega、VegaEmbed和D3的内部是如何工作的。如果这些库没有使用承诺,而是相当老式的回调,那么ANGLE的区域可能无法在async
?
console.log(texts);
最终在控制台中显示了一个包含4个文本SVG元素的集合。但console.log(texts.length);
显示0!- 怎么会这样?
- 如何让我的测试代码等到D3绘制完SVG之后才运行
expect
语句?
推荐答案
这是一个很好的问题,我遇到了与Ag-Grid
类似的问题,在执行断言之前必须等待呈现或其回调完成,并且没有像您提到的fakeAsync
、async/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呈现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!