モック、スタブ、擬似オブジェクトを使った効率的なユニットテスト1

When you're unit testing, you often want to test an individual unit of code without testing its dependencies. One common solution to this problem is to utilize the mock-object testing pattern. Though the mock-objects pattern can lead to a great working solution, many times, it is simply overkill. Extreme Programming (XP) espouses the principle: do the simplest thing that could possibly work. To this end, mock objects aren't always the simplest thing possible. This article introduces you to an approach for testing with stubs using a pattern called "pseudo objects."

Author's Note: The examples in this article are provided in Java, but the patterns that are discussed are language agnostic. You can use these patterns while programming in any object-oriented language.

ユニットテストをする時、依存性なしに一つコード単位をテストしたいとよく思うことだろう。この問題に対する一般的な解決策の一つは、モックオブジェクトテストパターンを利用することだ。このモックオブジェクトパターンは素晴らしく実用的な解決策となりえるが、とにかく手間がかかる。XPでは「役立ちそうなことのうちもっともシンプルなことをする」を信条としている。この目的のためには、モックオブジェトはいつも一番シンプルな選択肢になるとは限らない。この記事では”擬似オブジェクト”と呼ばれるパターンとスタブを使ったテスト方法を紹介する。

筆者注:この記事の中にあるサンプルコードはJavaで書かれている。しかしここで論じるパターンは言語を意識していない。これらのパターンはオブジェクト指向言語によるプログラミングでならなんにでも使える。

Testing Strategies, Mocks, and Stubs

テスト計画とモックとスタブ

In interaction-based unit testing, tests typically pass mock objects into methods so that the mock objects can verify the implementation of the code that is being tested. Mocks are fake objects that record the manner upon which they are operated and can verify whether they were operated on properly.

In state-based unit testing, real system objects are passed to the method that is being tested and the output of the method is asserted, but the implementation of the method is not tested. If a real system object is difficult to create within the context of the test, stubs are usually used instead. Stubs, like mock objects, are fake objects as well, but they usually have no logic or recording capability. Stubs just return canned data.

Author's Note: For a more in-depth discussion of the difference between mock objects (also called mocks) and stubs, as well as the differences between interaction and state-based unit testing, see Martin Fowler's recent paper "."

相互作用を中心としたユニットテストでは、普通モックオブジェクトがメソッドに渡されることになるので、モックオブジェクトはテストされているコードがきちんと実装されていることを実証できる。(この場合)モックは、それが操作される処理のされ方を記録するフェイクオブジェクトで、きちんと処理がされたかどうかを実証することができる。

状態中心のテストでは、実際のシステムのオブジェクトがテストされているメソッドに渡され、メソッドの出力がアサートされたとしても、メソッドの実装はテストされないことになる。もし実際のシステムのオブジェクトがテストのコンテキスト[状況]内で生成されるのが難しいものだったら、通常スタブが代わりに用いられる。モックと同じようにフェイクオブジェクトなのだが、スタブは通常ロジックや記録機能を持たない。ただあらかじめ準備されたデータを返すだけだ。

筆者注:モックオブジェクト(モックとも呼ばれる)とスタブの違いについて、同じく相互作用中心のテストと状態中心のテストの違いについて、より掘り下げた話は、マーティン・ファウラーの最近の論文「モックはスタブではない」を参照のこと*1

The main argument for choosing state-based unit testing over interaction-based unit testing is that interaction-based unit testing couples the tests to the implementation. I'll show you some examples of interaction-based unit testing using mocks, then I'll introduce you to state-based unit testing by showing you a simple pattern that will allow you to easily create stubs.

相互作用中心のユニットテストでなく状態中心のユニットテストを選ぶ時の主な理由は、相互作用中心のテストがテストを実装に連結させるところにある。これからモックを使った相互作用中心のユニットテストの例をいくつかお見せよう。そしてスタブを簡単に作れるシンプルなパターンを見せながら状態中心のユニットテストを紹介しよう。

*1:http://d.hatena.ne.jp/devbankh/20100210 で翻訳しています