題名の通り。 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が分断されてしまい、クラス定義が見えなくなったり食い違ってしまうのが原因らしい。 参考: - PowerMock and JMX - PowerMock | Google グループ -- http://groups.google.com/group/powermock/browse_thread/thread/e42919c6ff16abca/85cdce7f0b424c17 古い話題ではなく、上記スレッドなど今年(2010)の5月頃。対処された様子も無い。 自分の技術力や、コピペだけでの回避が明らかに無理なので、今回は潔く敗北を認めた。しゃーない、 ManagementFactory.getPlatformBeanServer()を外に出して、MBeanServerをコンストラクタ経由で注入することで対処した。 今日一日で、随分とMockito + PowerMockでの地雷源を走った気がする。 いやね、ホントね、こう地雷ばっか踏んでると、紹介記事とかで「こんなに簡単にMockが作れちゃう!staticメソッドだってほら簡単!」とかね、ウソかと、コードが単純すぎないかと。 JMX周りのコードなんて、ちょっと込み入ったサービスやデーモン的なコード書こうと思えば出てくるのは確実なわけで。 で、ちょろっとそういう「現実の」ライブラリを使っただけでもう手に負えなくなるなんて、地雷原に嵌って何時間も英語含めてドキュメントだのGoogle検索だのして。 こんな面倒くさいのが「TDD」の「現実」だとすりゃ、そりゃ流行らねーわな。