はじめに
「Spring Framework を使ったアプリケーションのテストコードを書いていて Theories
ランナーを使ってパラメタライズドテストとかしたいんだけどさ、DI しようとすると SpringJUnit4ClassRunner
ランナーとバッティングしてしまうんだよね… 困った困った」みたいなケースへの対処方法です。
Using JUnit Theories with Spring and Mockito に答えが書いてあるんですが、日本語での記事が見つからなかったのでメモメモしておきます。
ポイント
- テストランナーは
Theories
を使うよ -
SpringJUnit4ClassRunner
を使う普段のケースと同じく、- テストクラスには、
@ContextConfiguration
アノテーションを付与しておくよ - DI をしたいテストクラスのフィールドに
@Autowired
アノテーションを付与しておくよ
- テストクラスには、
- でもこのままだと DI されなくなっちゃうので、
@Before
アノテーションの付いたセットアップメソッドの冒頭でTestContextManager
クラスを使って DI を実現するよ
サンプルコード
import org.junit.Before;
import org.junit.experimental.theories.DataPoints;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestContextManager;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
/**
* Theories ランナーを用いつつ Spring の DI を実現する方法のデモ。
*/
@RunWith(Theories.class)
@ContextConfiguration(locations = "classpath:your-context.xml")
public class TheoriesWithDI {
/**
* DI したいオブジェクトのクラスはこちら
*/
@Component
public static class Converter {
public String convertToString(int num) {
return Integer.toString(num);
}
}
/** テストメソッドに与えられるパラメータ */
@DataPoints
public static int[] values = {1, 11, 222, 1234567};
/** このフィールドに DI したい */
@Autowired
private Converter converter;
/**
* DI とその他の初期化処理をします。
*
* @throws Exception
*/
@Before
public void setUp() throws Exception {
// 以下でこのインスタンスに対して DI することができる
new TestContextManager(getClass()).prepareTestInstance(this);
// その他の初期化処理...
}
@Theory
public void testConvert(int num) {
// exercise
String result = converter.convertToString(num);
// verify
assertThat(result, is(Integer.toString(num)));
}
}