ニセモノ

29 Jan 2017

前回kumabook/yakusokuというPromiseライブラリを作った。 これは業務でes3を書いていて困ったから作ったものである。 もう一つ困っているものがあった。テスト用のモックライブラリである。 現在JavaScriptでモックライブラリのデファクトは Sinon.JSである。 テストフレームワークJasmine (もしくはそのフォークのJest)にはモックAPIが付属している。 テストフレームワークとしてはmochaを使っているので、まあSinon.JSが使うのが普通の流れだ。 ただ、どうも実装が大きい。5000行ぐらいある。 もっとシンプルでいいからサイズを小さくして欲しい。 やはりNodeJS用のライブラリは富豪的である。

というわけでシンプルなモックライブラリを作ることにした。 どういうAPIにすべきか色々調べてみると、testdouble.jsというのが割と流行り始めている気配を感じた。 早速APIを見てみると、確かになかなかスッキリしている。 厳密にはspyとstubとmockの違うみたいなのだが、 そうは言っても実際問題そんなに区別しなくて良いことも多い。 testdouble.jsのそこを区別しない思想に好感がもてる。 他にもドキュメントがやたらと教育的で勉強になる。 なので、APIデザインはtestdouble.jsを参考にすることにした。

2週間前の週末に大半の部分を実装して出来上がったのが kumabook/nisemono である。基本は

だけである。そのニセモノの関数の振る舞いをnisemono.expects()で規定できる

nisemono.expects(func).withArgs(1, 2, 3).returns(6)

引数1, 2, 3 が渡された場合は6を戻り値として返す。

他にも

のバリエーションがある。 関数が呼ばれたかはfunc.isCalledで取得できる。

実際今のプロジェクトに投入しようとした時に毎回オブジェクトの全てのメソッドを差し替えるのが 辛かったので、既存のオブジェクトのメソッドをニセモノの関数に置き換えた「ニセモノのオブジェクト」を作るnisemono.obj()も追加で作成した。

var obj = {
  method1:  function() { return 1; },
  method2:  function() { return 2; },
  property: 'property'
};

こんなオブジェクトがあったら

var niseObj1 = nisemono.obj(obj);
nisemono.expects(niseObj1.method1).returns('nise1');
nisemono.expects(niseObj1.method2).returns('nise2');

こんな感じでオブジェクトのニセモノをサクッと作れる。 さらにonlyexceptでホンモノのままにしておきたいメソッドを指定できるので、 オブジェクトの特定のメソッドのテストを書く時に利用できる。

ここまで作って自分のユースケースは満たせたので、

など諸々行って一旦リリース。

小さいライブラリはこの辺の作業も重厚にならなくて楽しい。

「ニセモノ」という名前も結構気に入っている。

動的言語の世界ではダックタイピングというものがある。 「あるものがガーガー鳴くならそれはアヒルと見なして良い」というような発想のものである。 「ホンモノ」だろうが「ニセモノ」だろうが関係ない。 大事なのは「何をするか」であり「どう振る舞うか」である。 「ホンモノ」なのか「ニセモノ」なのかそれは他人が勝手に貼るラベルである。

ただ、自分自身は騙すことはできない。syrup 16gのニセモノを聞き直してそんなことを思った日曜の朝である。

そろそろ、最後の休日出勤に向かう時間である。

Tweet
comments powered by Disqus