🦁
Jestを使ってReact Hook Form + Yupのテストをする
React Hook FormとYupを使ったフォームのテストをJestで書いてみました。
- Reactを使ったフォームのレンダリングは行わずに、フォームのロジックのみをテストします。
- フォームに値をセットして、フォーム送信時に使われる handleSubmit で出力される最終データをチェックします。
- スキーマ定義によって出力データが意図しない結果になるバグがあり、コンパクトに検証するために作成したテストです。
testing-libraryのrenderHookを使って React Hook Form のフォームへのアクセスを得る
今回は Testing Libraryを使って React Hook のテストを行います。
React Hook Formはフォームの状態管理を行う useForm というカスタム・フックを提供しています。
renderHookでuseFormをレンダリングします。
import { renderHook } from '@testing-library/react-hooks';
import { useForm } from 'react-hook-form';
const reactHookFormResult = renderHook(() =>
useForm({
resolver: yupResolver(CowSchema),
mode: 'onChange',
})
);
);
こちらの記事を参考にしました。
setValue を使ってフォームに値をセットする
React Hook Formで値をセットするのには setValue を使います。
setValueはuseStateの更新関数なのでTesting Libraryが提供する act の中で呼び出します。
const { setValue, handleSubmit } = reactHookFormResult.result.current;
act(() => {
setValue('cowGroupId', '1');
setValue('motherCowUid', '0249452288');
});
handleSubmitでフォーム・データを取り出す
フォームのデータを handleSubmit を使って読み出します。
handleSubmitはコールバックを呼び出すインターフェースになっているので、Jestのコールバック呼び出しテストの書き方を使っています。
it('母牛の個体識別番号', (done) => {
handleSubmit((data) => {
expect(data.cowGroupId).toBe('1');
expect(data.motherCowUid).toBe('0249452288');
done();
})();
});
コールバックの終わりで done を呼び出します。
完成したコード
import { renderHook, act } from '@testing-library/react-hooks';
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
describe('個体識別番号', () => {
const CowSchema = yup.object().shape({
cowGroupId: yup.number().umSelectNumber().label('群番号(群名称)').required(),
motherCowUid: yup
.string()
.umNumberString()
.label('母牛の個体識別番号')
.maxLength(10)
.test('motherCowUid', '10桁入力してください', function (value) {
return String(value).length === 10;
}),
});
const reactHookFormResult = renderHook(() =>
useForm({
resolver: yupResolver(CowSchema),
mode: 'onChange',
})
);
const { setValue, handleSubmit } = reactHookFormResult.result.current;
it('母牛の個体識別番号', (done) => {
act(() => {
setValue('cowGroupId', '1');
setValue('motherCowUid', '0249452288');
});
handleSubmit((data) => {
expect(data.cowGroupId).toBe('1');
expect(data.motherCowUid).toBe('0249452288');
done();
})();
});
});
まとめ
React Hook FormのテストをJestで書いてみました。
React Hooksのレンダリングなど複雑な構成になりますが、一度書いてしまうと今後は同じ書き方で異なるパターンのテストができそうです。
Discussion