📝

【Google Maps API】@googlemaps/jest-mocksを使ってテストコードを書こう

2024/06/23に公開

この記事について

  • Google Map APIを使ったクラスやモジュールのテストをかけるようになりましょう。今回は@googlemaps/jest-mocksを使ってテストを書きましょう。Maps JavaScript API のテストが容易になるらしい。

https://github.com/googlemaps/js-jest-mocks

先に結論を3つ

  • Google Mapをモックしてくれるモジュールに@googlemaps/jest-mocksというものがある
  • 使い方はinitializeメソッドを呼び出し、Google Map APIを用いたテストデータを作成、実行するだけ
  • MarkerやPolygonなどのGoogle Mapオブジェクト、クリックやドラッグイベント時の挙動もテストすることが可能

@googlemaps/jest-mocksとは

Google Mapをモックしてくれるモジュールです。本来ならば、テストを実行するたびにgoogle map apiを実行する必要がありますが、それが不要になります。(ちなみに、約28000回までは無料でAPIを実行することが可能です。mockを使わないと、、、想像したくないですね。)

customizePolylineというクラスのテストを実行したいと仮定します。isEditableというメソッドが意図した値を返してくれるかというテストをしたいと思います。

    class CustomizePolyline {
        id: string;
        polyline: google.maps.Polyline;
        createdId: number;

        isEditable(operatorActorType: number, hasAdminAuthority: boolean): boolean {
            // 省略
        }
    }
    describe('customizePolylineクラスのメソッドで、操作者によって編集可能かを判定するメソッドであるisEditableのテスト', () => {
        const customizePolyline = new CustomizePolyline(
            '01HY05BFHVNKRT3KSEP440Q845',
            new google.maps.Polyline({
                path: [
                    new google.maps.LatLng({ lat: 34.40882247741932, lng: 136.6821998287318 }),
                    new google.maps.LatLng({ lat: 34.40882247741933, lng: 136.6821998287319 }),
                ],
                ...mapFrameCommonOptions,
            });,
        );


        test('操作者が管理者の場合、ポリラインの編集可能かのフラグがtrueであること', () => {
            expect(customizePolyline.isEditable(OPERATOR_ACTOR_TYPE, true)).toBeTruthy();
        });
    });

もしこれがないとテストを実行した時は、以下のような結果が返ってきます

    FAIL  tests/unit/customizePolyline.spec.ts
    ● Test suite failed to run

    ReferenceError: google is not defined

        6 |
        7 | const initialPolyline = () => {
        >  8 |   const map = new google.maps.Map(document.createElement('div'));
            |               ^
        9 |   const polyline = new google.maps.Polyline({
        10 |     path: [
        11 |       new google.maps.LatLng({ lat: 34.40882247741932, lng: 136.6821998287318 }),

google is not definedが返ってきます。ということで@googlemaps/jest-mocksを使っていきましょう。

詳細

手順は以下のとおりです。

  1. initializeメソッドを呼び出す
  2. テストデータを作成する
  3. テストを実行する

1. initializeメソッドを呼び出す

テストを実行する前に、Google Maps API のグローバル名前空間を設定しなければなりません。mockを動かすための準備です。
先ほどのテストコードで言うと以下のように導入します。

import { initialize } from "@googlemaps/jest-mocks";

describe('customizePolylineクラスのメソッドで、操作者によって編集可能かを判定するメソッドであるisEditableのテスト', () => {
    initialize(); // これです

    const customizePolyline = new CustomizePolyline(
        '01HY05BFHVNKRT3KSEP440Q845',
        new google.maps.Polyline({
            path: [
                new google.maps.LatLng({ lat: 34.40882247741932, lng: 136.6821998287318 }),
                new google.maps.LatLng({ lat: 34.40882247741933, lng: 136.6821998287319 }),
            ],
            ...mapFrameCommonOptions,
        });,
    );


    test('操作者が管理者の場合、ポリラインの編集可能かのフラグがtrueであること', () => {
        expect(customizePolyline.isEditable(OPERATOR_ACTOR_TYPE, false)).toBeTruthy();
    });
});

2. テストデータを作成する

テストを実行するために、データを作成しましょう。作成するデータはメソッドに閉じ込めておきます。各テストで使いわますためです。
また、1で導入したinitializeの後に実行しましょう。
作成したデータはmockInstancesから取得することが可能です

import { initialize } from "@googlemaps/jest-mocks";
import { initialize, mockInstances, Polyline } from '@googlemaps/jest-mocks';

// ここでテストデータを作成
const initialPolyline = () => {
  const map = new google.maps.Map(document.createElement('div'));
  const polyline = new google.maps.Polyline({
    path: [
      new google.maps.LatLng({ lat: 34.40882247741932, lng: 136.6821998287318 }),
      new google.maps.LatLng({ lat: 34.40882247741933, lng: 136.6821998287319 }),
    ],
    ...mapFrameCommonOptions,
  });
  polyline.setMap(map);
};


describe('customizePolylineクラスのメソッドで、操作者によって編集可能かを判定するメソッドであるisEditableのテスト', () => {
    initialize(); 
    initialPolyline(); // initializeした後に、テストデータを作成

    // 作成したポリラインを取得
    // 取得するオブジェクトは配列であることに注意
    const mockPolyline = mockInstances.get(Polyline);

    const customizePolyline = new CustomizePolyline(
        '01HY05BFHVNKRT3KSEP440Q845',
        mockPolyline[0],
    );

    test('操作者が管理者の場合、ポリラインの編集可能かのフラグがtrueであること', () => {
        expect(customizePolyline.isEditable(OPERATOR_ACTOR_TYPE, true)).toBeTruthy();
    });
});

3. 実行する

>  yarn test:unit tests/unit/customizePolyline.spec.ts

 PASS  tests/unit/customizePolyline.spec.ts
  customizePolylineクラスのメソッドで、操作者によって編集可能かを判定するメソッドであるisEditableのテスト
    ✓ 操作者が管理者の場合、ポリラインの編集可能かのフラグがtrueであること (1 ms)

無事に成功しました

最後に

今回は@googlemaps/jest-mocksを使って、Google Map APIを使ったテストコードを書いてみました。これを使うことで、MMarkerやPolygonなどのGoogle Mapオブジェクト、クリックやドラッグイベントなどのイベント時に発火する処理など、Google Map APIに関する様々なテストコードを容易に書くことができます。うちのチームにとってとても重宝するモジュールになるでしょう。

参考

Discussion