Chapter 05

実例:単体テストとリファクタリング #1

とっくり
とっくり
2022.06.14に更新

ここから、「純粋関数は最高だー!」とつい思ってしまうようなリファクタリングをしていきますよ。

前回の記事からの続きです。

https://zenn.dev/tockri/books/dcaf6c55e64448/viewer/9adba7

リファクタリング…の前に

さて、リファクタリングをするために必要不可欠なものがあります。そう、単体テストですね。テスト無しとか@t_wadaの(略)

Jestの導入

JavaScriptのテストフレームワークはいろいろありますが、ここでは使い始めるのが簡単なJestを使いましょう。

$ npm install jest --save-dev

これだけでそのディレクトリ以下にJestをインストールできます。

$ npx jest (テストファイル)

で指定したテストを実行できます。簡単ですね。

単体テストの準備

前回のコードはこちらです。ここから手を加えていきます。

単体テストの準備1. ファイル分割

スクリプト中、validateName、validateZip、validateAddress、validateMailの4つは純粋関数なので簡単に単体テストができますが、このままではJestで扱えないので、上記4つの純粋関数だけをvalidator.jsとして分離します。残りのjQueryでDOMやイベントを扱っている部分をform.jsとします。

validator.js内の関数は後で扱いやすくするために一つのオブジェクトValidatorにまとめます。

validator.js
const Validator = {};

Validator.validateName = function(state) {
  :
  :
}
Validator.validateZip = function(state) {
  :
  :
}

単体テストの準備2. node.js用にexport

validator.jsはブラウザからは<script>タグで読み込みますが、テストのときはnode.jsのrequireで読み込みます。どちらからでも読み込めるように、validator.jsの末尾にちょっと汚いですがおまじないを。

validator.js
// テスト用コード。ブラウザでは実行されない
if (typeof module !== "undefined"
    && typeof module.exports !== "undefined") {
  module.exports = Validator;
}

もちろんbabelやwebpack等を使ってファイルを連結すればこういうハックは必要ありませんが、今回は構成を単純にするためにこのような形で。

単体テストコード

validator.test.jsという名前でJest用のテストコードを書きます。場所はどこにおいても良いです。

validator.test.js
const Validator = require("../js/validator");

test("validateName check empty", () => {
 const result = Validator.validateName({
   value: "",
   valid: true,
   message: ""
 });
 expect(result).toStrictEqual({
   value: "",
   valid: false,
   message: "名前を入力してください"
 });
});

 :
 :
 :

ここまでのコードをgithubに上げているのでご覧ください

結局JestのAPIは2つ(test , expect.toStrictEqual)しか使ってないです。
ディレクトリ構成はこうなっています。

js/
    +- form.js
    +- validator.js
test/
    +- validator.test.js
form.html
package.json

テスト実行

このディレクトリで

$ npx jest test/validator.test.js

とするとテスト実行できます。

$ npx jest test/validator.test.js --watch

とすると、関連するファイルを保存するたびに自動的にテストが走ります。

リファクタリングは…長くなったので次回!