技術/TDD/Javaでstaticメソッドをmockする
技術 / TDD / Javaでstaticメソッドをmockする
id: 1227 所有者: msakamoto-sf
作成日: 2013-07-27 21:38:45
カテゴリ: Java TDD プログラミング
powermockがオススメ・・・というか他に知らないんですが。ただし、staticメソッドやSystem ClassLoaderによりロードされるJDKコアクラスをmockする必要が発生する場合、それ以前の問題としてそもそもアーキテクチャが不味くてリファクタリングした方が良いような状況だったりします。後述しますが、可能な限りstaticメソッドのmockやJDKコアクラスをmockする手法は避けてください。ぶっちゃけ地雷原です。
メリットを遥かに上回る(というか実際トラブルで嵌る)デメリット群:
- staticメソッドのmockやシステムクラスのmockを使いはじめると、JUnitなどのテストランナーを"@RunWith"を指定してpowermockが提供する専用のクラスローダ上で動かす必要があったりします。そのため、他に"@RunWith"アノテーションが必要なテストライブラリを併用する場合に不都合が出てくるかもしれません。
- 内部的には独自クラスローダの中でバイトコードを操作してmock専用のクラスを動的に構築するなど、かなり「ゴツイ」処理を行なっています。そのため、クラスの構成や処理内容によっては、思わぬ所で副作用が発生し、非常に原因究明の難しいエラーが発生する場合があります。 というか、ありました。 (具体的な内容は忘れましたが。)
- クラスローダ周りのトラブルはJVMのバイトコードのVerifierとか、JDKのClassLoaderの内部処理など相当低レイヤーで追うのが難しい領域で発生し、StackTraceのメッセージだけでは何が起こっているのかすら分からないことがあります。
- → 一度トラブルになると、それを収めるのに相当な時間を費やすことになる可能性が高いです。
ということで、個人的にはstaticメソッドやJavaのシステムクラスをmockしたいような場合、powermockを使って頑張ってmockするのではなく、以下の様な妥協案を探ることをオススメします。
- リファクタリングでstaticメソッドを追い出したり、
- システムクラスの処理をラップしてmockしやすくしたり、
- そこまでセンシティブなコードは自動化を諦める、など。
以下の記事を読んでみると、staticメソッドやSystem ClassLoaderにより読み込まれるJDKコアクラスをmockするのがどれほどセンシティブな処理であるか理解いただけるかと。
- How to Mock Static Methods - Michael Minella
- Classloader Deep-Cloning without Serialization – Jayway
- Mocking static methods in Java system classes – Jayway
プレーンテキスト形式でダウンロード
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2013-07-27 21:59:24
md5:25f9c1d01fd6fcd2ca6fc5379e041c5e
sha1:99d6e388b364f639cc6b3c68b8cd698a0452321c