サードパーティライブラリの中で requestAnimationFrame を使って非同期な処理をしている。テストコード中でその処理が終わってから値を確認したり別の操作をしたりしたい。どうするか? なおこの非同期処理は単なる関数で、返り値は別の目的に使われているので変えられないとする。

テストコード中からのリクエストに応じてresolveを露出したプロミスを作る関数を作り、サードパーティ実装の側に「resolveがnullでないなら呼ぶ」というコードを足した。 サードパーティの非同期処理の関数の引数や返り値を変えると修正範囲が広くなって嫌。この方法なら数行の修正ですむ。 修正はサードパーティのコードを直接書き換えるのではなく、jest.spyOn的な方法で差し替えるのが良い。今回は既に別の目的で差し替えていたのでそれを利用した。

test.ts

test("foo", async () => {
  let p = getCanvasViewUpdatePromise();
  ...
  await p;
  ...

target.ts

let _canvasViewUpdatePromise;
let _resolve: ((arg: unknown) => void) | null = null;
 
export const getCanvasViewUpdatePromise = () => {
  _canvasViewUpdatePromise = new Promise(res => {
    _resolve = res;
  }).then(() => {
    _resolve = null;
  });
  return _canvasViewUpdatePromise;
};

target.ts

    if (_resolve !== null) {
      _resolve(0);
    }

from Jestメモ