最近、Jest
を使ってテストコードを頻繁に書き始めたので、自身の使い方整理のため、以下雑にメモを残しておく。
test('null', () => { const n = null; expect(n).toBeNull(); // null一致 expect(n).toBeDefined(); // undefined以外一致 expect(n).not.toBeUndefined(); // undefinedではない expect(n).not.toBeTruthy(); // Truthyではない expect(n).toBeFalsy(); // Falsyである }); test('0', () => { const z = 0; expect(z).not.toBeNull(); // nullではない expect(z).toBeDefined(); // undefined以外一致 expect(z).not.toBeUndefined(); // undefinedではない expect(z).not.toBeTruthy(); // Truthyではない expect(z).toBeFalsy(); // Falsyである }); test('数値', () => { const value = 2 + 2; expect(value).toBeGreaterThan(3); // value > 3 expect(value).toBeGreaterThanOrEqual(3.5); // value >= 3.5 expect(value).toBeLessThan(5); // value < 5 expect(value).toBeLessThanOrEqual(4.5); // value <= 4.5 expect(value).toBe(4); // value = 4 expect(value).toEqual(4); // value = 4 }); test('浮動小数点', () => { const value = 0.1 - 0.2; //expect(value).toBe(-0.1); このように書くと、丸め込み誤差が原因で期待通りに動作しない expect(value).toBeCloseTo(-0.1); // これならば正しく動く }); test('正規表現', () => { expect('team').not.toMatch(/I/); // 正規表現に一致しない expect('Christoph').toMatch(/stop/); // 正規表現に一致 }); test('配列', () => { const shoppingList = [ 'diapers', 'kleenex', 'trash bags', 'paper towels', 'milk', ]; expect(shoppingList).toContain('milk'); // 配列に含まれているか expect(new Set(shoppingList)).toContain('milk'); // Setに含まれているか }); test('例外', () => { function compileAndroidCode() { throw new Error('you are using the wrong JDK'); } expect(() => compileAndroidCode()).toThrow(); // throwされているか expect(() => compileAndroidCode()).toThrow(Error); // throwのErrorが呼ばれているか expect(() => compileAndroidCode()).toThrow('you are using the wrong JDK'); // messageの一致 expect(() => compileAndroidCode()).toThrow(/JDK/); // 正規表現も可 }); test('予定', () => { test.todo('テストの予定を立てれる') }) test('モック', () => { // モック関数を作る const mockFn = jest.fn() mockFn .mockImplementationOnce( () => { return '返り値1' }) .mockImplementationOnce( () => { return '返り値2' }) .mockImplementationOnce( () => { return '返り値3' }) expect(mockFn()).toBe('返り値1') // 1回目の呼び出し expect(mockFn()).toBe('返り値2') // 2回目の呼び出し expect(mockFn()).toBe('返り値3') // 3回目の呼び出し // モックインスタンスを作る const mockInsFn = jest.fn() mockInsFn .mockImplementation( () => { return { hoge: jest.fn() .mockImplementationOnce( () => { return 'hoge関数の返り値1' }) .mockImplementationOnce( () => { return 'hoge関数の返り値2' }), fuga: () => { return 'fuga関数の返り値' } } }) const mockIns = new mockInsFn() expect(mockIns.hoge()).toBe('hoge関数の返り値1') // hoge関数の1回目の呼び出し expect(mockIns.hoge()).toBe('hoge関数の返り値2') // hoge関数の2回目の呼び出し expect(mockIns.fuga()).toBe('fuga関数の返り値') // fuga関数の呼び出し }) // CDKを呼び出す上で必要なものを定義 import { SynthUtils } from '@aws-cdk/assert' import * as cdk from '@aws-cdk/core' import { SampleStack } from '../src/deploy/sampleStack' test('スナップショット', () => { const app = new cdk.App() const stack = new SampleStack(app, `SampleStack`, { stage: 'dev', roleName: 'sampleRole' }) expect(SynthUtils.toCloudFormation(stack)).toMatchSnapshot() }) /* // スナップショットの結果 // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`スナップショット 1`] = ` Object { "Resources": Object { "sampleRole5138FD4B": Object { "Properties": Object { "AssumeRolePolicyDocument": Object { "Statement": Array [ Object { "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": Object { "Service": "lambda.amazonaws.com", }, }, ], "Version": "2012-10-17", }, "ManagedPolicyArns": Array [ Object { "Fn::Join": Array [ "", Array [ "arn:", Object { "Ref": "AWS::Partition", }, ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", ], ], }, ], "RoleName": "sampleRole", }, "Type": "AWS::IAM::Role", }, }, } `; */
感想
Jest
は使ってみた感じ、むちゃくちゃ便利だ。
とにかくモックが簡単で、関数やインスタンスが作りやすい印象を受けた。
スナップショットも取得することができ、イマドキ感も感じる。
試しに、CDKのCloudFormationテンプレートのスナップショットを取得してみたが、これは使えそうだ。個人的には、CloudFromationのテンプレートテストはそこまで必要性を感じていないのだが、スナップショット残しておくだけでも、差分確認ができるという点で便利だと思えた。
まだまだ使い慣れていないので、ドキュメントを読みつつ、さらなる使い方を学んでいきたい。