- ベストアンサー
Easy Mockでstaticメソッドのmock化はできるか?
- Easy Mockではprivateメソッドはmock化できないとサイトに記述されていたが、同様にstaticメソッドもmock化できないのか疑問がある。
- publicメソッドは問題なくmock化できるが、staticメソッドをmockに使用すると「no last call on a mock available」というエラーが発生する。
- 実際に動かしてみたが、予想通りに動作しない。これが設定やプログラムミスなのか、Easy Mockの仕様なのか判別できない。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
privateメソッドやstaticメソッドに関してのご質問ですので、 Class Extension を使用しているものと仮定してお答えします。 EasyMock で偽装できるのは、オーバーライドできるものだけのようです。 ですので、フィールドやprivate/static/finalのメソッドなどは偽装できないのかと。 ちなみに、staticメソッドはサブクラスで同じシグネチャーのメソッドを実装できますが隠蔽されるだけです。くわしくは参考URLなどを見て下さい。
その他の回答 (1)
- root139
- ベストアンサー率60% (488/809)
> テストコードからWebApplicationContextUtilsのMockを渡せなければ、どの道無理・・・ 渡せなければ、おっしゃる通り、無理かと思います。 ですが、もし getRequiredWebApplicationContext メソッドが static ではなかった場合、下記の様にすれば、EasyMock で偽装は出来ます。 ・テスト対象クラスにインスタンスフィールドとして、WebApplicationContextUtilsオブジェクトを持つ。 ・それをコンストラクタかsetterメソッドで置き換えられるようにする。 実際には WebApplicationContextUtils のラッパークラスを作って、テスト対象クラスではそれを使うようにすれば、テスト可能になると思います。 例) -------------------------------------------------------------- public class WebAppContextService { public ApplicationContext getRequiredWebApplicationContext(ServletContext sc) { return WebApplicationContextUtils.getRequiredWebApplicationContext(sc); } } ------------------------------------------------------------------ また、 staticメソッド等を含めたクラス単位での偽装が可能な DJUnit というものも在りますので、これなどを使えば現状のテスト対象(本番)コードでもテストができるかとは思います。 http://works.dgic.co.jp/djwiki/Viewpage.do?pid=@646A556E6974 ただ、テストがしやすいコードを書くことによって設計が改善されるということもとても重要ですので、極力、リファクタリングなどによってMockオブジェクトの挿入が可能にすることをお勧めします。 http://capsctrl.que.jp/kdmsnr/wiki/bliki/?cmd=view&p=StaticSubstitution&key=static DIの考え方も、具象クラスへの依存をコード中から出来るだけ取り除くことが柱になっています。 http://kakutani.com/trans/fowler/injection.html 自動単体テスト関しては、最近出版された「レガシーコード改善ガイド」が非常に参考になると思います。(原書は5年ほど前ですが) http://www.amazon.co.jp/dp/4798116831/
お礼
質問内容だけでなく、色々と教えて頂けてとても助かりました。 アドバイス頂いた事を検討して、どのように進めるか考えたいと思います。 本当に有難うございました。一人で調べていて煮詰まっていたので助かりました。
お礼
素早いご回答有難うございます。 すみません、Class Extensionの方になります。 なるほど、staticも偽装できないのですね。 私がいまテストしようとしているクラスは下記のようになりますので、Easy Mockでは無理そうですね。 ServletContext sc = pageContext.getServletContext(); ApplicationContext context = WebApplicationContextUtils.getRequiredWebApplicationContext(sc); Sample s = context.getBean(id); s.execute(); カスタムタグなのですが、タグハンドラ内からSpringのDIでオブジェクトを取得して実行します。 pageContextはsetterがあるのでMockを渡せますが、WebApplicationContextUtilsのstaticメソッドを最終的に呼び出してしまいます。 getRequiredWebApplicationContextがstaticメソッドでなければEasy Mockで試験できたのでしょうか。 URLについてもオーバライドと隠蔽についても、今までよく知りませんでしたので参考になりました。
補足
>getRequiredWebApplicationContextがstaticメソッドでなければEasy Mockで試験できたのでしょうか。 仮にstaticでなくてもカスタムタグ内でnewしていたら(テストコードからWebApplicationContextUtilsのMockを渡せなければ)、どの道無理という認識で合ってますでしょうか。