Deno でフロントエンド向けのライブラリやツールをテストするには、グローバル変数の document
オブジェクトをポリフィルしましょう。
Deno で document
をポリフィル手段はいくつか選択肢がありますが、筆者は jsr:@b-fuze/deno-dom
というパッケージをよく使っています。
以下のようなコードでグローバル変数の document
をポリフィルできます。
dom_polyfill.ts
import { DOMParser } from "jsr:@b-fuze/deno-dom";
(globalThis as any).document = new DOMParser().parseFromString(
"<body></body>",
"text/html",
);
上の書き方だと、空の内容のページがある状態でテストをすることが出来ます。
ページの内容が空ではなく、何らかのコンテンツが必要になる場合は、以下のように HTML を書き換えることが出来ます。
document.body.innerHTML = `<div>ここにテストに必要な任意の HTML を書く</div>`;
ポリフィルのタイミングの注意点
ポリフィル設定時の注意点として、ポリフィルは必ず別ファイルに分離して、テストファイルの先頭から読み込むようにしましょう。
以下のように、テストファイルの冒頭でポリフィルをしても、依存モジュールの方がポリフィルより先に実行されてしまい、ポリフィルが間に合わない場合があります。
悪い例
import { DOMParser } from "jsr:@b-fuze/deno-dom";
(globalThis as any).document = new DOMParser().parseFromString(
"<body></body>",
"text/html",
);
import "some-frontend-library";
// ^-- このモジュールの中身は上のポリフィルより先に実行される
// この時点ですでに document に依存している場合、エラーになる
Deno.test("テストケース1", () => {});
Deno.test("テストケース2", () => {});
良い例
import "./dom_polyfill.ts"; // <= ポリフィリがまず実行される
import "some-frontend-library"; // <= このモジュールはすでにポリフィルされた環境で動く
Deno.test("テストケース1", () => {});
Deno.test("テストケース2", () => {});
参考
上のレポジトリは筆者が開発しているフロントエンドライブラリです。Deno を使って開発していて、上で紹介した方法を利用して Deno ランタイムでテストを実行しています。