Spring Boot + npm + Geb で入力フォームを作ってテストする ( その42 )( Form.js のテストを Jest で書く2 )
概要
記事一覧はこちらです。
Spring Boot + npm + Geb で入力フォームを作ってテストする ( その41 )( IntelliJ IDEA で Javascript を debug する ) の続きです。
- 今回の手順で確認できるのは以下の内容です。
- Spring Boot + npm + Geb で入力フォームを作ってテストする ( その40 )( Form.js のテストを Jest で書く ) から引き続き src/main/assets/js/lib/class/Form.js のテストを書きます。
参照したサイト・書籍
- jQuery - Category: Event Object
https://api.jquery.com/category/events/event-object/
目次
- class 属性を変更するメソッドのテストを書く
- Validation 用メソッドのテストを書く
- IntelliJ IDEA の 2017.3 から coverage をエディタ上に表示できる
- 次回は。。。
手順
class 属性を変更するメソッドのテストを書く
resetValidation メソッド
以下のテストを書いて、
describe("class 属性を変更するメソッドのテスト", () => { describe("resetValidation メソッドのテスト", () => { test("入力チェック成功時(has-success)は has-success が削除される", () => { document.body.innerHTML = ` <div class="form-group has-success" id="form-group-name"> <div class="control-label col-sm-2"> <label class="float-label">お名前</label> </div> <div class="col-sm-10"> <div class="row"><div class="col-sm-10"> <input type="text" name="lastname" id="lastname" class="form-control form-control-inline" value="" placeholder="例)田中"/> </div></div> <div class="row hidden js-errmsg"><div class="col-sm-10"> <p class="form-control-static text-danger"><small>ここにエラーメッセージを表示します</small></p> </div></div> </div> </div> `; let form = new Form([]); expect($("#form-group-name").hasClass("has-success")).toBe(true); expect($(".js-errmsg").hasClass("hidden")).toBe(true); form.resetValidation("#form-group-name"); expect($("#form-group-name").hasClass("has-success")).toBe(false); expect($(".js-errmsg").hasClass("hidden")).toBe(true); }); test("入力チェックエラー時(has-error)は has-error が削除されてエラーメッセージが非表示になる", () => { document.body.innerHTML = ` <div class="form-group has-error" id="form-group-name"> <div class="control-label col-sm-2"> <label class="float-label">お名前</label> </div> <div class="col-sm-10"> <div class="row"><div class="col-sm-10"> <input type="text" name="lastname" id="lastname" class="form-control form-control-inline" value="" placeholder="例)田中"/> </div></div> <div class="row js-errmsg"><div class="col-sm-10"> <p class="form-control-static text-danger"><small>ここにエラーメッセージを表示します</small></p> </div></div> </div> </div> `; let form = new Form([]); expect($("#form-group-name").hasClass("has-error")).toBe(true); expect($(".js-errmsg").hasClass("hidden")).toBe(false); form.resetValidation("#form-group-name"); expect($("#form-group-name").hasClass("has-error")).toBe(false); expect($(".js-errmsg").hasClass("hidden")).toBe(true); }); }); });
実行するとテストは成功しました。
setSuccess メソッド
以下のテストを書いて、
test("setSuccess メソッドのテスト", () => { document.body.innerHTML = ` <div class="form-group" id="form-group-name"> </div> `; let form = new Form([]); expect($("#form-group-name").hasClass("has-success")).toBe(false); form.setSuccess("#form-group-name"); expect($("#form-group-name").hasClass("has-success")).toBe(true); });
実行するとテストは成功しました。
setError メソッド
以下のテストを書いて、
test("setError メソッドのテスト", () => { document.body.innerHTML = ` <div class="form-group" id="form-group-name"> <div class="control-label col-sm-2"> <label class="float-label">お名前</label> </div> <div class="col-sm-10"> <div class="row"><div class="col-sm-10"> <input type="text" name="lastname" id="lastname" class="form-control form-control-inline" value="" placeholder="例)田中"/> </div></div> <div class="row hidden js-errmsg"><div class="col-sm-10"> <p class="form-control-static text-danger"><small>ここにエラーメッセージを表示します</small></p> </div></div> </div> </div> `; let form = new Form([]); expect($("#form-group-name").hasClass("has-error")).toBe(false); expect($(".js-errmsg").hasClass("hidden")).toBe(true); expect($(".js-errmsg small").text()).toBe("ここにエラーメッセージを表示します"); form.setError("#form-group-name", "お名前を入力してください"); expect($("#form-group-name").hasClass("has-error")).toBe(true); expect($(".js-errmsg").hasClass("hidden")).toBe(false); expect($(".js-errmsg small").text()).toBe("お名前を入力してください"); });
実行するとテストは成功しました。
Validation 用メソッドのテストを書く
convertAndValidate メソッド
以下のテストを書いて、
describe("Validation 用メソッドのテスト", () => { describe("convertAndValidate メソッドのテスト", () => { const idFormGroup = "#form-group-name"; const idList = ["#name", "#age"]; test("全ての要素に focus していると converter, validator が呼ばれる", () => { let form = new Form(idList); let event = $.Event("test"); const converter = jest.fn(); const validator = jest.fn(); form.forceAllFocused(form); form.convertAndValidate(form, event, idFormGroup, idList, converter, validator); expect(converter).toBeCalled(); expect(validator).toBeCalled(); expect(event.isPropagationStopped()).toBe(false); }); test("全ての要素に focus していないと converter, validator は呼ばれない", () => { let form = new Form(idList); let event = $.Event("test"); const converter = jest.fn(); const validator = jest.fn(); form.convertAndValidate(form, event, idFormGroup, idList, converter, validator); expect(converter).not.toBeCalled(); expect(validator).not.toBeCalled(); expect(event.isPropagationStopped()).toBe(false); }); test("converter, validator に undefined を渡してもエラーにならない", () => { let form = new Form(idList); let event = $.Event("test"); form.forceAllFocused(form); expect(() => { form.convertAndValidate(form, event, idFormGroup, idList, undefined, undefined); }).not.toThrow(); expect(event.isPropagationStopped()).toBe(false); }); test("validator が Error オブジェクトを throw すると event.stopPropagation() が呼ばれる", () => { let form = new Form(idList); let event = $.Event("test"); const converter = jest.fn(); const validatorThrowError = jest.fn().mockImplementation(() => { throw new Error(); }); form.forceAllFocused(form); form.convertAndValidate(form, event, idFormGroup, idList, converter, validatorThrowError); expect(event.isPropagationStopped()).toBe(true); }); }); });
実行するとテストは成功しました。
IntelliJ IDEA の 2017.3 から coverage をエディタ上に表示できる
IntelliJ IDEA 2017.3 から Jest のテストを実行するコンテキストメニューに「Run ... with Coverage」が表示されるようになりました。また、このメニューからテストを実行すると Jest のレポートファイルを見なくてもエディタ上で実行された部分が分かります。
例えば「Run 'focus イベントに関するメソッドのテスト' with Coverage」を実行してみると、
テストが実行されて成功し、
Coverage の Window が表示されて、Form.js の 39% の行がテストされたことが分かります。
Form.js をエディタで開いてみると、画面の左側にテストが実行された箇所が緑で、実行されていない箇所が赤で表示されます。
テストの実行された/されていない箇所を表示する色はデフォルトでは見にくい色だったので、単純な緑、赤に変更しています。色が表示されている部分にマウスカーソルを移動して左クリックした後、「Edit coverage colors」のアイコンをクリックします。
「Editor | Color Scheme | General」ダイアログが表示されるので、緑は 00FF00 へ、
赤は FF0000 へ変更しています。
次回は。。。
もう少し Jest でテストを書いてみます。jQuery.ajax 呼び出し時の非同期処理や、setTimeout で遅延して処理を実行する場合のテストを書く予定です。
それにしても IntelliJ IDEA 2017.3 + Jest の環境だと、Javascript のテストを書いたり実行したり、coverage を確認したり、うまく動かない時に debug 実行したりも、Java の時とたいして変わりがないですね。開発しやすい印象です。テスト実行時の Node.js のパラメータ指定(--inspect
等)も IntelliJ IDEA が自動でセットしてくれるのは便利です。
履歴
2017/12/22
初版発行。