SpringbootでHierarchicalContextRunnerを使用して、テストの階層化を実現します。
依存関係
pom.xml
<dependency>
<groupId>de.bechte.junit</groupId>
<artifactId>junit-hierarchicalcontextrunner</artifactId>
<version>4.12.1</version>
<scope>test</scope>
</dependency>
実装
- Controllerクラスのテストを想定してます。
HogeControllerTest.java
@RunWith(HierarchicalContextRunner.class) --(1)
public class HogeControllerTest {
/**
* ベースクラス
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@WebAppConfiguration
public static class HogeControllerTestBase { --(2)
@ClassRule
public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule(); --(3)
@Rule
public final SpringMethodRule springMethodRule = new SpringMethodRule(); --(3)
@Autowired
protected MockMvc mockMvc;
@MockBean
protected HogeService service;
}
/**
* 一覧画面のテスト
*/
public class HogeControllerTest_ほげ一覧画面 extends HogeControllerTestBase { --(4)
@Test
@WithMockUser(username="test")
public void indexTest_正常系() throws Exception {
// 何かしらのテストコード
}
}
/**
* 編集画面のテスト
*/
public class HogeControllerTest_ほげ編集画面 extends HogeControllerTestBase { --(4)
@Test
@WithMockUser(username="test")
public void updateTest_正常系() throws Exception {
// 何かしらのテストコード
}
}
}
(1) ランナー指定
- 階層化を実現するためにHierarchicalContextRunnerをランナーとして指定します。
- 階層化する手法としてはenclosed.classもありますが、こちらのほうが柔軟に階層化することができるようです。
(2) 基底クラス
- 非テスト対象として宣言するため、staticなインナークラスとして定義します。
- 付与するアノテーションはお決まりのやつです。ここらへんはメタアノテーション化してもいいかも。
(3) SpringClassRule、SpringMethodRule
- JUnitが提供しているTheoriesやParameterizedランナーを使用したいときや、Mockitoなどのサードパーティが提供しているランナーを使用したい時に指定します。
Spring JUnit 4 Rules
(4) テスト実装クラス
- 基底クラスを継承して、publicで非staticなクラスとします。