Javaのテストをするときに、JMockitやMockitoなどのモックライブラリを使うことがあると思います。
Mockitoはちょっとしたことをしたいときに便利なのですが、実デバイスのシミュレータなど、モックにかなり複雑な処理をさせたい場合は、JMockitの方が便利という印象です。
で、このJMockitなのですが、JUnit4.5以上と共存させるには、@RunWith(JMockit.class)と指定する必要があります。これをしない場合は、ライブラリの読み込み順序の指定しないといけないので、めんどうくちゃい。@RunWith(JMockit.class)を使いたい。
しかし、@Theoryを使うには@RunWith(Theories.class)とする必要があります。つまり、単純には共存できなくてどーしよ、となりました。
え、JUnit5を使えと?いや、うん………、そりゃまそうなんだけどさぁ。キゾンコードノイコウメンドウクサイジャンカー.
Theoriesランナーを拡張する
JMockitランナーって何やってるのさ、と覗いてみたら、なんと、BlockJUnit4ClassRunnerを拡張してstatic { Startup.initializeIfPossible(); }としてるだけだった。
jmockit1/JMockit.java at master · jmockit/jmockit1 · GitHub
あれ?これってもしかして、Theoriesを拡張して、static { Startup.initializeIfPossible(); }するだけのランナー作ったらいけるんちゃう?とやってみたら、行けてしまった。
package my.mockit; import org.junit.runners.*; import org.junit.runners.model.*; import org.junit.experimental.theories.*; import mockit.internal.startup.*; public class TheoriesWithJMockit extends Theories { static { Startup.initializeIfPossible(); } public TheoriesWithJMockit(Class<?> testClass) throws InitializationError { super(testClass); } }
これでクラスパスの順序とか気にせずに、JMockitでモックしまくりながら、Theoriesでクルクル回せるぜ!
まだまだJUnit4も使えますなぁ。
私がJUnit5に移行するのはいつになるのですかなぁ。
とりあえず、Theories相当の拡張機能とかあれば移行するかなぁ。クラスで引数を選択してくれるのが好きなんだよな。
TestFactoryも慣れれば行けるのか?