📑

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

2022/05/01に公開

やりたいこと

以前作成したフロントエンド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の結果

参考記事

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/create

余談(どうやって作ったのか)

フロントエンドで、実際に<input type="file" multiple />から取得したFilelistをconsole.logで表示させて、必要な要素をググって、その再現方法を調べて、作りました。

脚注
  1. フロントエンドJavascriptのみでCloud Storageにファイルをアップロードする / Akira Kashihara https://zenn.dev/akira_kashihara/articles/a7c0c0df48f5a0 (2022-04-16閲覧) ↩︎

Discussion