LoginSignup
3
2

More than 3 years have passed since last update.

Jest で テストをテスト仕様書っぽく書いてみよう

Last updated at Posted at 2020-07-14

jest-simple-template

いきなりですが、Jestの機能の一つ、describe.each を利用して、テストドキュメントっぽく テストを書く ライブラリを作りました。

このパッケージを使うと、テストがこんな感じで書けます。

import handler from '../src/target'
import mocks from './mocks'

/* data input */
let request = {}

/**
 * Test Case Definition
 *
 * [0]: test description
 * [1]: request(input)
 * [2]: expect(output)
 */
const testCase = [
    [
        // [0]: description
        {
            name: 'OK',
            description: 'should return succeeded response'
        },
        // [1]: request
        request,
        // [2]: expected
        (result: {}) => {
            expect(result).toBe(1)
        }
    ],
    [
        // [0]: description
        {
            name: 'Duplicated',
            description: 'should return duplicate something error'
        },
        // [1]: request
        request,
        // [2]: expected
        (result: {}) => {
            expect(result).toBe('error')
        }
    ]
    /* ここに、テストブロックをどんどん足していく */

]

describe.each(testCase)('Test Category1', (d, r, e) => {
    beforeEach(() => {
        jest.resetAllMocks()
    })
    const testMeta = d as TestCaseMetaData
    it(`${testMeta.name}:${testMeta.description}`, async () => {
        if (mocks.hasOwnProperty(testMeta.name)) {
            mocks[testMeta.name]()
        }

        // @ts-ignore
        const result = await handler(r)
        const expected = e as (result: any) => void
        expected(result)
    })
})

このテンプレートパッケージで、私的にはそこそこ快適にテストが書けていると感じたので、共有することにします。

コンセプト

コンセプトとしては、Jest の describe.each は、引数に input、outputもまぜまぜにした Array を取り、ぐるぐる回す方式なので、配列の各 Index にこちらで意味を与えてやれば、テスト仕様書っぽく書けるのでは? という発想が発端です。

describe.each に渡す配列のindexに以下のような意味を持たせます。

  • index[0] - テストの説明
  • index[1] - テストへの入力
  • index[2] - 出力の検証

この発想は Rails の CoC(Convention Over Configuration) が元になっていて、ある程度名前付けなどを規約として決めてしまったほうがコードが読みやすく、短くなるのではないか? というところから来ています。

mocking

上の方法だけだと、Mockを書くのにテストが大きくなってしまい、せっかくのドキュメントが見づらいことになってしまったので、mockは別のファイルにしました。 ここでも CoC の考えかたを取り入れて、 先ほどの説明で、index[0] で定義したnameと一致するものを探して取ってくるようにしました。


const mocks: Mocks = {
    OK: () => {
      // write the code of mocking some objects
    },
    Duplicated: () => {
      // write the code of mocking some objects
    }
}

export default mocks

結果、テストファイルは、describe.each が一つだけ。
テストの内容は、jest.describe の Arrayで表現した形が整いました。

みなさんのテストコードを書くのが少し楽になってくれたらよいなと思います。

3
2
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
3
2