進行状況の追跡を始めよう
Trailhead のホーム
Trailhead のホーム

その他のコンポーネントのモック

学習の目的

この単元を完了すると、次のことができるようになります。

  • sfdx-lwc-jest パッケージに付属するスタブについて説明する。
  • Jest 設定を上書きする方法を理解する。
  • コンポーネントを開発環境外でテストする。
  • 外部コンポーネントのスタブを作成する。

基本コンポーネントのモック

sfdx-lwc-jest パッケージを使用すれば、Lightning Web コンポーネントで Jest を実行できます。このパッケージによってテストを実行するために必要な Jest 設定が行われ、一切変更する必要がありません。以前のモジュールでも広く使用されています。このパッケージには、Lightning 名前空間のすべてのコンポーネントに対応する一連のスタブ (テストされるモジュールと連動するコンポーネントをシミュレートするプログラム) が含まれます。Lightning 基本コンポーネントもすべてこの対象です。スタブは node-modules/@salesforce/sfdx-lwc-jest ディレクトリの src/lightning-stubs ディレクトリにインストールされます。

test-lwc プロジェクトの lightning-stubs ディレクトリ

付属のデフォルトスタブを上書きする必要のあることがあります。その場合は、Jest 設定を上書きしてから、カスタムスタブを作成します。では、Lightning ボタンでこの操作を実行する手順を見ていきましょう。

最初に、Visual Studio Code でカスタムスタブのディレクトリを設定します。

  1. force-app ディレクトリを右クリックし、[New Folder (新しいフォルダ)] を選択します。
  2. 新しいディレクトリの名前に「test」と入力します。
  3. 新しい __test__ ディレクトリを右クリックし、[New Folder (新しいフォルダ)] を選択します。
  4. 新しいディレクトリの名前に「jest-mocks」と入力します。
  5. 新しい jest-mocks ディレクトリを右クリックし、[New Folder (新しいフォルダ)] を選択します。
  6. 新しいディレクトリの名前に「lightning」と入力します。

これが Lightning 基本コンポーネントのスタブのルートになります。

次に、Salesforce DX プロジェクトのルートにある jest.config.js という名前のファイルを更新し、sfdx-lwc-jest からデフォルト設定をインポートして、Jest 設定を上書きします。

  1. jest.config.js ファイルを開きます。
  2. 新しいファイルの “add any custom configurations here” (ここにカスタム設定を追加) というコメントの後に、次のコードブロックを入力します。
      moduleNameMapper: {
        '^lightning/button$': '<rootDir>/force-app/test/jest-mocks/lightning/button'
      }
    moduleNameMapper に注意します。これは Jest に lightning-button のスタブがある場所を伝えるものです。最初のダッシュがスラッシュに変換され、残りのコンポーネント名がケバブケースからキャメルケースになります。スラッシュを使用する理由は、モジュールリゾルバーが 1 つ目のダッシュの前のすべてを名前空間として処理するためです。ここでは、<rootDir> が Salesforce DX ワークスペースのルートに対応付けられます。
  3. ファイルを保存します。

次は、button スタブを先ほど作成した lightning ディレクトリに追加しましょう。

  1. 先行の手順で作成した lightning ディレクトリを右クリックし、[New File (新しいファイル)] を選択します。
  2. 新しいファイルの名前に「button.html」と入力します。
  3. 新しいファイルに次のコードブロックを入力します。
    <template></template>
  4. ファイルを保存します。
  5. lightning ディレクトリを右クリックし、[New File (新しいファイル)] を選択します。
  6. 新しいファイルの名前に「button.js」と入力します。
  7. 新しいファイルに次のコードブロックを入力します。
    import { LightningElement, api } from 'lwc';
      
    export default class Button extends LightningElement {
      @api disabled;
      @api iconName;
      @api iconPosition;
      @api label;
      @api name;
      @api type;
      @api value;
      @api variant;
    }
  8. ファイルを保存します。

この 2 つのファイルは、lightning-stubs フォルダにある lightning-button ファイルのコピーです。必要に応じて、Jest テストの基本の lightning-button をこのコピーで上書きできます。

これで、sfdx-lwc-jest に付属するデフォルトスタブを上書きできるようになりました。では、コンポーネントが他の名前空間や管理パッケージにある場合はどうなるのでしょうか? 数か所を調整するだけでこうしたケースにも対応できます。これらのコンポーネントについて見ていきましょう。

その他のコンポーネントのモック

まず、別の名前空間にあるコンポーネントをモックします。この場合は、Jest テストに失敗する Lightning Web コンポーネントを設定してから、修正をモックアウトします。

  1. Visual Studio Code で新しい Lightning Web コンポーネントを作成します。
  2. 「otherComponents」という名前を設定します。
  3. 今回は Jest テストを別の方法で作成します。ターミナルで次の CLI コマンドを実行します。
    sfdx force:lightning:lwc:test:create -f force-app/main/default/lwc/otherComponents/otherComponents.js

このコマンドは __tests__ フォルダと otherComponents.test.js テストファイルを自動的に作成します。この時点ですでにインポートが存在し、初期の describe ブロックも存在し、1 回目は失敗するテストが設定されています。 

この 1 を 2 と想定していたため、このテストを実行すると失敗します。まずこの点を修正し、次に他のコンポーネントがスタブ化されていない場合にどのようなエラーが生じるのか確認しましょう。

  1. otherComponents.test.js テストファイルを開き、1 を 1 と想定してテストを更新します。
    expect(1).toBe(1);
  2. ファイルを保存して、テストを実行します。
  3. このテストは合格します。

次に、別の名前空間のコンポーネントを LWC に追加します。

  1. otherComponents.html ファイルを開いて、template タグの内側に次のコードを追加します。
    <thunder-hammer-button onclick={makeNoise}></thunder-hammer-button>
  2. ファイルを保存して、テストを実行します。
  3. 今度は次の理由でテストに失敗します。
    Test suite failed to run
      Cannot find module 'thunder/hammerButton' from 'otherComponents.html'

<thunder-hammer-button> コンポーネントは別の名前空間にあり、ローカルの lwc ディレクトリにないため、スタブを作成して、これらのコンポーネントの名前をモックファイルに対応付けるよう Jest 設定を更新する必要があります。

まず、名前空間を表す thunder ディレクトリを追加する必要があります。次に、ファイルを追加して、スタブ化します。

  1. force-app/test/ ディレクトリの jest-mocks ディレクトリを右クリックし、[New Folder (新しいフォルダ)] を選択します。
  2. 新しいディレクトリの名前に「thunder」と入力します。
  3. thunder ディレクトリを右クリックし、[New File (新しいファイル)] を選択します。
  4. 新しいファイルの名前に「hammerButton.html」と入力します。
  5. 新しいファイルに次のコードブロックを入力します。
    <template></template>
  6. ファイルを保存します。
  7. 新しい thunder ディレクトリを右クリックし、[New File (新しいファイル)] を選択します。
  8. 新しいファイルの名前に「hammerButton.js」と入力します。
  9. 新しいファイルに次のコードブロックを入力します。
    import { LightningElement, api } from 'lwc';
      
    export default class HammerButton extends LightningElement {
      @api label;
      // any other implementation you may want to expose here
    }
  10. ファイルを保存して、テストを実行します。
  11. テストに失敗します。Jest 設定ファイルを更新する必要があります。
  12. jest.config.js を開いて、moduleNameMapper: { 行のすぐ下に次の行を追加します。
    '^thunder/hammerButton$': '<rootDir>/force-app/test/jest-mocks/thunder/hammerButton',
  13. ファイルを保存して、テストを実行します。
  14. このテストは合格します。

今後、作業している LWC が、Salesforce DX プロジェクトのローカル LWC ディレクトリにない別の LWC をインポートすることがあります。その別の LWC が管理パッケージの一部である場合や、ソースファイルと一緒にダウンロードされなかったような場合です。スタブがなければ Jest に失敗します。テストしてみましょう。

  1. otherComponents.html ファイルを開いて、1 つ目の template タグの後に次のコードを追加します。
    <c-display-panel errors={error} notes={messages}></c-display-panel>
  2. ファイルを保存して、テストを実行します。
  3. コンポーネントが見つからないため、テストに失敗します。

この問題はスタブで修正できます。まずスタブを作成し、次に Jest 設定を更新します。

  1. force-app/test/ ディレクトリの jest-mocks ディレクトリを右クリックし、[New Folder (新しいフォルダ)] を選択します。
  2. 新しいディレクトリの名前に「c」と入力します。
  3. c ディレクトリを右クリックし、[New File (新規ファイル)] を選択します。
  4. 新しいファイルの名前に「displayPanel.html」と入力します。
  5. 新しいファイルに次のコードブロックを入力します。
    <template></template>
  6. ファイルを保存します。
  7. 新しい c ディレクトリを右クリックし、[New File (新しいファイル)] を選択します。
  8. 新しいファイルの名前に「displayPanel.js」と入力します。
  9. 新しいファイルに次のコードブロックを入力します。
    import { LightningElement, api } from 'lwc';
      
    export default class ErrorPanel extends LightningElement {
      @api errors;
      @api notes;
      // any other implementation you may want to expose here
    }
    コンポーネントのコールで渡される各パラメータに api デコレータが付いています。
  10. ファイルを保存します。
  11. jest.config.js を開いて、moduleNameMapper: { 行のすぐ下に次の行を追加します。
    '^c/displayPanel$': '<rootDir>/force-app/test/jest-mocks/c/displayPanel',
  12. ファイルを保存して、テストを実行します。
  13. このテストは合格します。

素晴らしい! これであらゆる Lightning Web コンポーネントのテストを記述する方法を習得しました。また、これらのスタブの実装を必要に応じて高度化あるいは単純化することもできます。

リソース