Это хороший вопрос, у меня есть похожие проблемы с Ag-Grid
, когда мне приходится ждать завершения рендеринга или его обратных вызовов, прежде чем я сделаю утверждения, и нет хорошего способа, как вы упомянули с fakeAsync
, async/done
, et c. По крайней мере, ничего из того, что я нашел.
Я нашел способ сделать служебную функцию, например, так:
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);
};
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
});
Вы упомянули setTimeout
, работающую со значением 0. Это работает, потому что мы помещаем то, что находится внутри setTimeout
, в конец очереди стека вызовов, потому что она работает асинхронно. Делать это таким образом все еще хорошо, но мне нравится, как тесты читаются с подходом waitUntil
.