"Design How Your Objects Talk Through Mocking"を見た

Konstantin Kudryashov - Design How Your Objects Talk Through Mocking at Laracon EU 2014 - YouTube

BehatやPhpSpecの作者である@everzetによるLaracon EU 2014での講演です。 英語が苦手なので翻訳することはできませんが印象的かつ聞き取れた部分を要約して紹介します。


  • モックはデータベース接続等の遅い部分をテストから分離して速くするためのものだと思われているが、それは誤解だ(そのような目的ではFake Implementationを使う)。

  • モックは、結果や状態に注目したクラシカルなTDDでは隠されていたオブジェクト間のメッセージングをさらけだし、設計の問題を明らかにするデザインツール

  • メッセージングではなく、結果をさらけ出そうとするのなら、コードにさらにgetterを追加することを強いられるだろう

  • 存在しないメソッド、インタフェース、クラスをモックしたことを知らせてくれないような壊れたMocking Frameworkを使わない

  • 自分が所有していないオブジェクトをモックしない

  • (QAより)

    Q:例えばS3のようなサードパーティー製のAPIを使う場合はどうすべきか。

    A:インターフェースを作り、それを実装したS3と通信するクラスを作る。そのクラスのインテグレーションテストを書き、インターフェースをモックする。

    インテグレーションテストはPHPUnitや他のテスティングフレームワークで書き、実際にS3にファイルが保存されるかをテストする。


感想。

サンプルコードはPHPUnit+Prophecyという構成で書かれています。説明のためにより広く知られている記法を選んだのではないかと思いますが、PhpSpecで書けばより簡潔なコードになるでしょう。

Mockを使った開発の問題として、Mockと実装が食い違ってしまうという点が挙げられる場合があります。しかしそれはMocking Frameworkがチェックすべきだと@everzetは指摘しています。多くのMocking Frameworkでは存在しないクラスやメソッドをMockすることができますが、PhpSpec/Prophecyではエラーとなります。

個人的な経験としては、PhpSpecを学ぶことで、Mock、システム境界、Hexagonal Architecture が一つの線で結ばれ、The GOOS bookに書かれていることが初めて理解できたように思います。

最初にThe GOOS Bookを読んだときは、「モックするのは自分の持っている型だけ」の意味が理解できなかったのですが、PhpSpecでコードを書いてみると、そもそもモックを書くのは次に実装しようとしているコラボレーターの場合が多く、モックは設計なんだ、既に存在しているものをモックする意味は無いんだということが自然に理解できたように思います。

The GOOS Bookって良い本だけどちょっと難しいので、同じようなテーマでPhpSpecで書かれたものがあればいいなあ。

実践テスト駆動開発 (Object Oriented SELECTION)

実践テスト駆動開発 (Object Oriented SELECTION)