u-ryo's blog

various information for coding...

Spock and JMockit

| Comments

バイトのtestで、Spockでさらっとtest書いて、 いざ全pattern cross check! と思ったら、 無限loopになるpatternが多くて。 @Timeout導入でサクッと、と思ったら、 loop回るのが早くて凄いmemoryと時間を食って、 @Timeoutでは抑えきれません。 うーむ、それじゃぁGroovyのmetaClassでmethodの振る舞いを変更だ! と思ったら、どうやっても振る舞いが変わりません。 悩んだ末、GroovyのmetaClassでの再定義は、 外側のJava classには及ばない(Groovyの世界の中だけ)、と結論。 仕方無いじゃぁJMockitだ! って思ったんですが、今度はSpockとJMockitは相容れないようで、

1
Caused by: java.lang.UnsupportedOperationException: Attempted to redefine class loaded from custom class loader

なのでJAVA_OPTS=-javaagent:.../jmockit-1.37.jarをつけて実行すると今度は、

1
mockit.internal.ClassFile$NotFoundException: Unable to find class file for Test2$1

spockは諦めました。

ならばせめてJUnit5だ! と思ったんですが、build.gradleで、

1
junitAnt 'org.apache.ant:ant-junit4:1.10.1'

と指定しているので、敢え無く撃沈。 調べるとどうも、JUnit5とAntを組み合わせる動きはないんですよね。 それでも Ant を使いたい人のための JUnit 5というのもありましたけど、これは、

1
<java fork="true" classname="org.junit.platform.console.ConsoleLauncher">

で無理矢理実行してるだけですから、ちょっと違います。 こちとら、build.gradleからant.junitAnt(...)で呼んでいるので、 ConsoleLauncherだと困るんです(→どうやって書いたらいいかよくわからない)。

結局、JUnit4 + JMockit で書きました。 TimeoutExpectedException@Ruleにしてちょこっと今っぽくしましたけど、 そのくらいが関の山でした。

ant.junitAnt(...)fork:trueにして、また更に junit4.jarよりjmockit.jarを先に書いておかないと IllegalStateExceptionが出る(gradle + jmockitでjava.lang.IllegalStateExceptionって出たので対応)、 というのでそう書いたしgradle --stacktraceしてload順確認したんですけど、 それでもException出たので、

1
jvmarg(line:"-javaagent:${configurations.jmockit.asPath.split(':')[0]}")

を入れて漸く動きました。

けど、折角JMockit入れたのに、 やっぱり別の時にはTimeoutも必要で。 JUnit4だと@RuleつけてTimeout.millis(200)でいいんですね今。 そしたら、JMockitで振る舞い変えなくても、 GroovyでなくJavaならTimeoutだけで済むじゃーないですかー! うぁーん。

あとはParameterized Testにしました。 JUnitParamsが簡便そうです。 何がいいって、JUnit4標準の方法だとinstance fieldがparameterになるので、 全methodについて回っちゃいませんか? というのが不安で。 JUnitParamsなら、明示的に単一methodに対してparameter指定できるので安心です。

...ダメです。JUnitParams使うと、Timeout効かないことがわかりました。 悲しい。

Comments