Jestを使ったユニットテストで、UUIDなどのランダム生成値を含むテストをする

最近JestとReactの勉強を兼ねてgutenbergにPRいろいろ出してるのですが、その中で「おぉー」ってなったものを一つ。 ランダムな値が混ざる関数 こういう関数があるとします。 import uuid from […]

広告ここから
広告ここまで

目次

    最近JestとReactの勉強を兼ねてgutenbergにPRいろいろ出してるのですが、その中で「おぉー」ってなったものを一つ。

    ランダムな値が混ざる関数

    こういう関数があるとします。

    import uuid from 'uuid/v4';
    export function createNotice( status, content, options = {} ) {
        const {
            id = uuid(),
            isDismissible = true,
        } = options;
        return {
            type: 'CREATE_NOTICE',
            notice: {
                id,
                status,
                content,
                isDismissible,
            },
        };
    }
    

    よくよく見ると、notice.idの値がランダム生成になっています。
    そのため通常のアサーションではうまくいきません。

    describe( 'createNotice', () => {
        const status = 'status';
        const content = <p>element</p>;
        it( 'should return CREATE_NOTICE action when options is empty', () => {
            const result = createNotice( status, content );
            expect( result ).toEqual( {
                type: 'CREATE_NOTICE',
                notice: {
                    status,
                    content,
                    isDismissible: true,
                    id: 'string',
                },
            } );
        } );
    } );
    

    これだとこういうエラーになる

    Summary of all failing tests
     FAIL  editor/test/actions.js
      ● actions › createNotice › should return CREATE_NOTICE action when options is empty
    
        expect(received).toEqual(expected)
    
        Expected value to equal:
          {"notice": {"content": <p>element</p>, "id": "string", "isDismissible": true, "status": "status"}, "type": "CREATE_NOTICE"}
        Received:
          {"notice": {"content": <p>element</p>, "id": "2dd9488b-28f0-4b4c-b1d1-536524e04672", "isDismissible": true, "status": "status"}, "type": "CREATE_NOTICE"}
    
        Difference:
    
        - Expected
        + Received
    
          Object {
            "notice": Object {
              "content": <p>
                element
              </p>,
        -     "id": "string",
        +     "id": "2dd9488b-28f0-4b4c-b1d1-536524e04672",
              "isDismissible": true,
              "status": "status",
            },
            "type": "CREATE_NOTICE",
          }
    
          at Object.<anonymous> (editor/test/actions.js:430:19)
          at process._tickCallback (internal/process/next_tick.js:109:7)
    

    toMatchObject()expect.any()を組み合わせる

    こういうケースの場合、JestだとtoMatchObject()expect.any()を組み合わせると良いみたいです。

    describe( 'createNotice', () => {
        const status = 'status';
        const content = <p>element</p>;
        it( 'should return CREATE_NOTICE action when options is empty', () => {
            const result = createNotice( status, content );
            expect( result ).toMatchObject( {
                type: 'CREATE_NOTICE',
                notice: {
                    status,
                    content,
                    isDismissible: true,
                    id: expect.any( String ),
                },
            } );
        } );
    } );
    

    notice.idは少なくともString型の何かが返ってくるので、expect.any( String )とします。

    参考:https://github.com/WordPress/gutenberg/pull/3787#pullrequestreview-80768414

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark