BuZ*_*uZz 2 jasmine d3.js vega angular angular9
我有一个通过 VegaEmbed ( https://github.com/vega/vega-embed )构建的 Angular 饼图组件,它使用 Vega 和 D3 作为底层图形依赖项。它通过提供标题和一些(键,值)对来呈现。我隔离了该组件,并修改了 main.ts 以从 Stackblitz 中运行 Jasmine 与您分享。在这个测试中,我正在检查饼图是否确实<text>为值“30%”呈现了 SVG标签 | “70%”与传奇“联合CEO/主席”| “单独的首席执行官/主席”。但是,它们似乎运行得太早了,而且 VegaEmbed+Vega+D3 仍在忙于构建 SVG。(我仅通过 Chrome 开发工具查看 DOM 就推断出要测试的内容)。
https://stackblitz.com/edit/angular-d3-pie-chart-unit-test
我已经尝试了一系列的事情:async, FakeAsync+ tick, jasmine.clock, 改变我的 Angular 组件中的 promises 逻辑等等......fixture.whenStable让我更近了一步,但texts声明的第 50 行仍然未定义。
我不知道 Vega、VegaEmbed 和 D3 的内部是如何工作的。如果这些库没有使用承诺,而是使用老式的回调,那么 Angular 的 Zones 可能无法在async?
让我有点困惑的是,console.log(texts);最终在控制台中显示了 4 个文本 SVG 元素的集合。却console.log(texts.length);显示0!
expect然后才运行语句?这是一个很好的问题,我有类似的问题Ag-Grid,我必须等待渲染或它的回调完成之前,我做的断言,有没有什么好办法像你提到的fakeAsync,async/done等至少没有,我已经找到。
我发现的一种方法是制作一个实用函数,如下所示:
import { interval } from 'rxjs';
.....
export const waitUntil = async (untilTruthy: Function): Promise<boolean> => {
while (!untilTruthy()) {
await interval(25).pipe(take(1)).toPromise();
}
return Promise.resolve(true);
};
Run Code Online (Sandbox Code Playgroud)
waitUntil将每 25 毫秒循环一次,直到提供的回调函数为真。时间长短取决于你。
因此,在您的测试中,您可以执行以下操作:
it('should render the chart', async(done) => {
// 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
done(); // call done to let the test this async test is done
});
Run Code Online (Sandbox Code Playgroud)
您提到setTimeout使用 0 值工作。这是有效的,因为我们将里面的内容放在setTimeout调用堆栈队列的末尾,因为它是异步运行的。这样做仍然很好,但我喜欢用这种waitUntil方法读取测试的方式。
| 归档时间: |
|
| 查看次数: |
2352 次 |
| 最近记录: |