home ホーム search 検索 -  login ログイン  | reload edit datainfo version cmd icon diff delete  | help ヘルプ

日記/2010/10/14/PowerMockでManagementFactory.getPlatformMBeanServer()→敗北

日記/2010/10/14/PowerMockでManagementFactory.getPlatformMBeanServer()→敗北

日記 / 2010 / 10 / 14 / PowerMockでManagementFactory.getPlatformMBeanServer()→敗北
id: 810 所有者: msakamoto-sf    作成日: 2010-10-14 19:31:13
カテゴリ: Java 

題名の通り。

PowerMock + Mockito で、

import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;
...
ObjectName name = ObjectName.getInstance("my.pkg:type=xxyy,name=wwzz");
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
mbs.invoke(name, "fooMethod", null, null);

この辺のコードをstubにしようとしたのだけれど、

ManagementFactory.getPlatformMBeanServer()

これをMockできない。

PowerMockito.mockStatic(ManagementFactory.class);
MBeanServer mockMbs = Mockito.mock(MBeanServer.class);
Mockito.when(ManagementFactory.getPlatformMBeanServer()).thenReturn(mockMbs);

コンパイルは通る。しかし、実行時に以下の例外が発生する。

org.mockito.exceptions.misusing.WrongTypeOfReturnValue: 
MBeanServer$$EnhancerByMockitoWithCGLIB$$911c39e9 cannot be returned by getPlatformMBeanServer()
getPlatformMBeanServer() should return MBeanServer

MBeanServer周りなど独自のClassLoaderを使っているらしい。そのため、コンパイルは通ったとしても実行時にClassLoaderが分断されてしまい、クラス定義が見えなくなったり食い違ってしまうのが原因らしい。

参考:

古い話題ではなく、上記スレッドなど今年(2010)の5月頃。対処された様子も無い。

自分の技術力や、コピペだけでの回避が明らかに無理なので、今回は潔く敗北を認めた。しゃーない、
ManagementFactory.getPlatformBeanServer()を外に出して、MBeanServerをコンストラクタ経由で注入することで対処した。

今日一日で、随分とMockito + PowerMockでの地雷源を走った気がする。

いやね、ホントね、こう地雷ばっか踏んでると、紹介記事とかで「こんなに簡単にMockが作れちゃう!staticメソッドだってほら簡単!」とかね、ウソかと、コードが単純すぎないかと。
JMX周りのコードなんて、ちょっと込み入ったサービスやデーモン的なコード書こうと思えば出てくるのは確実なわけで。
で、ちょろっとそういう「現実の」ライブラリを使っただけでもう手に負えなくなるなんて、地雷原に嵌って何時間も英語含めてドキュメントだのGoogle検索だのして。

こんな面倒くさいのが「TDD」の「現実」だとすりゃ、そりゃ流行らねーわな。


プレーンテキスト形式でダウンロード
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2010-10-14 19:51:16
md5:ffd85de31d5467015c30b81d46ca15b8
sha1:4f212e46a197f0a7b024b67c46aa66de64f90487
コメント
コメントを投稿するにはログインして下さい。