VueでJestで画面サイズの単体テストをやってみる


概要

画面サイズの変更を単体テストでテストしたかった。

環境

  • Vue3
  • Typescript
  • Jest

コード

まずはテスト駆動ぽくやるために、テストコードの方を記述する

describe("LogListContent", () => {
    test("画面のサイズによって、フラグが切り替わるか", (): void => {

        const wrapper = mount(LogListContent);

        //とりあえずPCサイズ
        resizeWindow(1440);

        //PCサイズの画面判定なので、mobileモードは偽値になっているはず
        expect(wrapper.vm.isMobileMode).toEqual(false)

        //mobileサイズをiPhoneSE2にする
        resizeWindow(740);

        //PCサイズの画面判定なので、mobileモードは真になっているはず
        expect(wrapper.vm.isMobileMode).toEqual(true)
    });
});

const resizeWindow=(x:number) =>{
    window = Object.assign(window, { innerWidth: x });
    window.dispatchEvent(new Event("resize"));
}

テスト対象のコンポーネントにて、isMobileModeでモバイルで見ているかPCなのかの真偽値を持たせて管理したいと思います。
resizeWindow関数で、画面サイズの値を更新しています。
Typescriptだと、window.innerWidthへ値を代入して更新しようとすると、読み取り専用だぞと怒られるので、
スマートではありませんが、Object.assingを使って更新しています。

  setup() {
    const isMobileMode = ref(false);

    /**
     * 画面サイズ変更時に変更イベントを検知しモバイルかどうか判断する
     */
    const changeWindowSize = () => {
      750 >= window.innerWidth
        ? (isMobileMode.value = true)
        : (isMobileMode.value = false);
    };

    //画面サイズが変更された時に発火するイベントを登録する
    //Vue3からcreatedは明示的に書かずにsetupに直接コードするためここにかく
    window.addEventListener("resize", changeWindowSize);

    //インスタンスが破棄された時に画面サイズ変更でのイベントを破棄する
    //破棄イベントは明示的に書かなくてはいけないので、Vue3でのdestroyedの役目であるonUnmountedを利用する
    onUnmounted(() => {
      window.removeEventListener("resize", changeWindowSize);
    });

    return {
      isMobileMode
    };
  },

Vueのコンポーネント側のコードはこんな感じになります。
三項演算子を使っている条件文のところで、750 >= window.innerWidthと画面幅をハードコーディングしていますが、
実際に使う場合には、定数を使ったりするなどでハードコーディングしないようにしましょう。
今回は説明用なのでハードコーディングしちゃってます。

Vue2でのライフサイクルにおける、createdにおける役割は今回は明示的に書かなくてもよくなりました。
setup関数の中がそれを担っているようなので、Vue2のような

  created(){
    window.addEventListener("resize", changeWindowSize);
   }

とは書かずに、ダイレクトにsetup関数に書いています。
このままだとこのコンポーネントのインスタンスが破棄されても、イベントは残り続けるので、イベントを削除する必要があります。
以前なら、destoryedで行っていましたが、Vue3ではそれがonUnmountedへと変更になりました。

これで画面サイズの変更を単体テストでテストすることができました。
Vue3になっても、単体テストのコードはVue2からあまり変更がないため、再度の覚え直しが少なくて楽かなと思います。