FileListをモックする(フロントエンドJavascriptテスト)

11659 ワード

やりたいこと

以前作成したフロントエンドJavascriptのみでCloud Storageにファイルをアップロードするコード[1]をライブラリ化しているところで、そのテストを書いています。そのときに、HTMLの<input type="file" multiple />から取得したFilelistのモックが必要となりました。この記事では、このFilelistを作るのに大変苦労したので、作成の仕方を書きたいと思います。
今回作成するモックに必要な条件は以下です。

  • オブジェクトの詳細な情報を表すためにObject.prototype.toString.callを使ってFileListを取得できる。
  • テスト対象の関数内でfor文を使ってFileListの一つずつのFileに対して処理を書けるようにする。

モック方法

環境

Vitest v0.9.3

コード

テスト対象の関数

sample.js
export const filesProcess = (fileList) => {
  if (
    Object.prototype.toString.call(fileList).split(" ")[1].slice(0, -1) !=
    "FileList"
  )
    throw Error("FileListを引数に入れるように!");

  for (let file of fileList) {
    console.log("ファイル名: " + file.name);
  }
};

テストコード

filelist.test.js
    it("てすと", () => {
      const file = new File(["foo"], "foo.txt", {
        type: "text/plain",
      });
      const file2 = new File(["this is test file"], "test.txt", {
        type: "text/plain",
      });
      const input = document.createElement("input");
      input.setAttribute("type", "file");
      input.setAttribute("name", "file-upload");
      input.multiple = true;
      let mockFileList = Object.create(input.files); // FileListを継承してオブジェクトを作る
      mockFileList[0] = file;
      mockFileList[1] = file2;
      Object.defineProperty(mockFileList, "length", { value: 2 });
      console.log("型の詳細: " + Object.prototype.toString.call(mockFileList));
      filesProcess(mockFileList);
      expect(1).toBe(1); //FileListの作成を試したいのでダミー
    });

実行結果

以下のようにconsole.logで出力された結果が確認できます。
FileListの結果

参考記事