概要
テスト対象のクラスで、application.propertiesの値を @Value
でインジェクションさせたフィールドを使ったメソッドを対象としたものがあったのですが、ちょっと苦戦したので残しておこうと思いました。
環境
- jdk1.8
- SpringBoot 1.5.13
どんな実装?
Hoge.java
@Repository
public class Hoge {
@Value("${hoge.threshold}")
private int threshold;
/* 略 */
public void extract(Object params) {
if (judge(params.getValue())) {
/* 処理 */
}
}
private boolean judge(int value) {
if (value > threshold) {
return true;
} else {
return false;
}
}
}
application.properties
hoge.threshold=100
HogeTests.java
@RunWith(SpringRunner.class)
@SpringBootTest
public class HogeTests {
@AutoWired
Hoge hoge;
@Test
public void testJudge() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method method = Hoge.class.getDeclaredMethod("judgeQueryDriver", String.class);
method.setAccessible(true);
assertThat(method.invoke(hoge, 101)).isEqualTo(true);
assertThat(method.invoke(hoge, 100)).isEqualTo(false);
}
}
どんなことが起こるか
稼働しているときは問題なくvalueインジェクションが効いているのですが、テストを実行すると、インジェクションが効かず失敗してしまいます...🤔
やってみたこと
次のことをやりましたが、反映されませんでした。
-
src/test/resources
を作成し(こういったテストケースの前例がなかったので新規に作る形になりました)、同じ内容のapplication.propertiesを配置 -
@SpringBootTest
の後ろに(properties = {"hoge.threshold=100"})
を追加 -
@PropertySource
または@TestPropertySource
でsrc/test/resourceに追加したapplication.propertiesを指定する -
@Before
がついたメソッドをHogeTestsに実装し、そのなかでReflectionTestUtils.setField
を実行
解決
-
judge()
のアクセシビリティをpublicに変更して試してみると、なんと正常に読み込みました。 - ただ、テストのためにpublicに変更するべき・・・?
- そもそもの実装設計の話として、こういった判定実装って同じクラスに実装せずにUtil的なクラスに実装してしまうのがいいのかもしれないですね。