以前からJUnit には、あまり執着することがなかった。
カバレッジ率の為に無駄に近い労力をかけたくもなく、動いて当たり前のテストケースを
書くセンスの無さが厭だったからである。
今日は、今更の JUnit のことを書いてみたくなった。
static メソッドのモックを書こう。というケース
powermock は JUnit5 に対応していない。らしい。
https://github.com/powermock/powermock
powermock を使わずにモックということで、org.mockito を使うのだが、その前にまず。。。
mockito-all と、mockito-core
mockito-all は、all と名のつくとおり、 hamcrest や、objenesis の依存を含めているので
これが良いように思っていた。。
mickito-all どうやら、1.10.18 を最後に 2.x の開発がとまっている様子で
static メソッドのモックを作る MockedStatic 生成ができない。
mockito-core を使わざるをえない。
モックインスタンス注入も、
MockitoAnnotations.initMocks(this);
と書いていたものから、
MockitoAnnotations.openMocks(this);
という記述に変える。initMocks は、非奨励になったのだ。
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>4.2.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-inline</artifactId> <version>3.4.0</version> <scope>test</scope> </dependency> <dependency> <groupId>net.bytebuddy</groupId> <artifactId>byte-buddy-agent</artifactId> <version>1.12.6</version> <scope>test</scope> </dependency>
あえて、簡単なサンプル
import javax.inject.Inject; public class Target{ @Inject private Foo foo; public String view() { // void execute() とい戻り値のないメソッド foo.execute(); // Some.value1() という String を返す static メソッド return "This is "+Some.value1() + ":"+ foo.getName().toUpperCase(); } }
この Target の view() をテストする。
Foo クラスをモックして、Some クラスの staticメソッドをモックする。
import static org.hamcrest.CoreMatchers.*; import org.hamcrest.MatcherAssert; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockedStatic; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; /** * Target Test */ @RunWith(JUnit4.class) public class TargetTest{ @Mock private Foo foo; @Before public void before() { MockitoAnnotations.openMocks(this); } @InjectMocks private Target target; @Test public void test() { try(MockedStatic<Some> mocked = Mockito.mockStatic(Some.class)){ mocked.when(()->Some.value1()).thenReturn("A"); Mockito.when(foo.getName()).thenReturn("abc"); String answer = target.view(); // 検証 assertEquals Assert.assertEquals("This is A:ABC", answer); // 検証 assertThat MatcherAssert.assertThat(answer, is("This is A:ABC")); // void メソッド execute() の実行回数 Mockito.verify(foo, Mockito.times(1)).execute(); }catch(Exception e){ e.printStackTrace(); Assert.fail(); } } }