LoginSignup
0
0

Salesforceアプリケーション開発をする際のメモ

Posted at

1. 目的

  • 忘れた時に見る
  • 検索した際に古い書き方がトップの方に出てきて間違えてしまうことがあったのを防ぎたい

2. 参考

3. メモ

Lightning Web Component - implementation

refreshApexで正常の場合、エラーの場合の挙動を定義する

refreshApex(this.wiredProperty)
    .then(() => {
      // 正常の場合の挙動を定義する
    })
    .catch(error => {
      // 正常の場合の挙動を定義する
    }
);

or

async someFunction() {
    try {
        await refreshApex(this.wiredProperty);
      // 正常の場合の挙動を定義する
    } catch (error) {
      // 正常の場合の挙動を定義する
    }
}

Lightning Web Component - test

基本的な記述

  • flushPromisesを使用して、コンポーネントの反映を行う
__tests_/demo.test.js
describe('c-demo', () => {
    afterEach(() => {
        while (document.body.firstChild) {
            document.body.removeChild(document.body.firstChild);
        }

        jest.clearAllMocks();
    });

    async function flushPromises() {
        return Promise.resolve();
    }

    describe('list of demos', () => {
        it('when data exists', async () => {
            const element = createElement('c-demo', {
                is: Demo
            });
            document.body.appendChild(element);

            // given:
            // - モック定義やテストのための事前操作を記述する
            const mockGetDemos = [
                { "id": 1, "name": "Foo", "description": "Foo Description" },
                { "id": 2, "name": "Bar" }
            ];
            getDemos.emit(mockGetDemos);

            // when:
            // - コンポーネントを更新する
            await flushPromises();

            // then:
            // - 確認対象を検証する
            const datatableElement = element.shadowRoot.querySelector('lightning-datatable');

            expect(datatableElement.data.length).toBe(2);
            expect(datatableElement.data).toEqual([
                { "id": 1, "name": "Foo", "description": "Foo Description" },
                { "id": 2, "name": "Bar" }
            ])
        });

}

@wireされたApexメソッドのテスト

  • 以下のような実装があるとする
demo.js
// ~ 省略 ~
import getDemos from '@salesforce/apex/DemoController.getDemos';

export default class Demo_page extends LightningElement {
    @wire(getDemos)
    demos;

// ~ 省略 ~
  • Apexメソッドのモック定義
    • createApexTestWireAdapterを使用する
__tests__/demo.test.js
// ~ 省略 ~
import getDemos from '@salesforce/apex/DemoController.getDemos';

jest.mock(
    '@salesforce/apex/DemoController.getDemos',
    () => {
        const {
            createApexTestWireAdapter
        } = require('@salesforce/sfdx-lwc-jest');
        return {
            default: createApexTestWireAdapter(jest.fn())
        };
    },
    { virtual: true }
);

    describe('demos', () => {

// ~ 省略 ~

  • Apexメソッドがデータを返す場合
__tests__/demo.test.js
    it('when data exists', async () => {

// ~ 省略 ~

        const mockGetDemos = [
            { "id": 1, "name": "Foo", "description": "Foo Description" },
            { "id": 2, "name": "Bar" }
        ];
        getDemos.emit(mockGetDemos);

// ~ 省略 ~

    }

  • Apexメソッドがエラーとなる場合
__tests__/demo.test.js
    it('when returned error to get data', async () => {

// ~ 省略 ~

        getDemos.error();

// ~ 省略 ~

    }

dispatchされたShowToastEventのテスト

  • 例として、wireされたApexメソッドがエラーの場合に、トーストを表示する
demo.js
    @wire(getDemos)
    getDemos(value) {
        this.demos = value;
        const { data, error } = value;
        if (error) {
            this.dispatchErrorToast();
        } else if (data) {
            // nop
        }
    }

    dispatchErrorToast() {
        this.dispatchEvent(
            new ShowToastEvent({
                title: 'Error loading Demo',
                message: 'fail to fetch records of demo',
                variant: 'error'
            })
        );
    }
__tests_/demo.test.js
import { ShowToastEventName } from 'lightning/platformShowToastEvent';

// ~ 省略 ~

describe('c-demo', () => {

// ~ 省略 ~

        it('when returned error to get data', async () => {
            const element = createElement('c-demo-page', {
                is: Demo_page
            });
            document.body.appendChild(element);

            // given:
            // - toast eventにモックされたハンドラーを定義する
            const toastHandler = jest.fn();
            element.addEventListener(ShowToastEventName, toastHandler);

            // - wireされたApexメソッドでエラーを発生させる
            getDemos.error();

            // when:
            // - コンポーネントを反映させる
            await flushPromises();

            // then:
            const datatableElement = element.shadowRoot.querySelector('lightning-datatable');

            expect(datatableElement).toBe(null);

            // - toast eventに定義したモックされたハンドラーに対して検証を行う
            expect(toastHandler).toHaveBeenCalled();
            expect(toastHandler).toHaveBeenCalledTimes(1);
        });
    });

force-app/test/jest-mocks/lightning/platformShowToastEvent.js
/**
 * For the original lightning/platformShowToastEvent mock that comes by default with
 * @salesforce/sfdx-lwc-jest, see:
 * https://github.com/salesforce/sfdx-lwc-jest/blob/master/src/lightning-stubs/platformShowToastEvent/platformShowToastEvent.js
 */

export const ShowToastEventName = 'lightning__showtoast';

export class ShowToastEvent extends CustomEvent {
    constructor(toast) {
        super(ShowToastEventName, {
            composed: true,
            cancelable: true,
            bubbles: true,
            detail: toast
        });
    }
}
  • jest.config.jsでモジュール定義する
    • moduleNameMapperの箇所で、lightning/platformShowToastEventを定義する
jest.config.js
const { jestConfig } = require('@salesforce/sfdx-lwc-jest/config');

module.exports = {
    ...jestConfig,
    modulePathIgnorePatterns: ['<rootDir>/.localdevserver'],
    moduleNameMapper: {
        '^lightning/platformShowToastEvent$': '<rootDir>/force-app/test/jest-mocks/lightning/platformShowToastEvent'
    }
};
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0