SpringBootでコマンドラインアプリ(コマンドラインから引数を受け取って実行するアプリ)を作る際には、本処理を実行するクラスにCommandLineRunner
の実装クラスとして作成することができます。
ですが、このCommandLineRunner
でユニットテストを書いた際に、テスト対象のクラスの本処理まで実行されてしまうという問題があります。
例えば、Testを実行しようとしただけで、バッチの本処理が動いてしまい、思わぬ動作をしてしまう、といったことが考えられます。
この問題の解決方法はないかとGithubのissueを探していたら、見つかりました。
https://github.com/spring-projects/spring-boot/issues/830
以下のような方法で記載することができるようです。
@SpringBootApplication
// profileが"test"以外のとき実行する
@Profile("!test")
public class App implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
@Override
public void run(String... arg0) throws Exception {
System.out.println("run!");
}
}
@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles("test")
public class AppTest {
@Test
public void contextLoads() {
}
}
以下テスト実行時のコンソールの出力です。
2016-11-01 23:32:46.962 INFO 42306 --- [ main] com.example.AppTest : Starting AppTest on xxx with PID 42306 (started by xxxxx in /xxx/xxx/workspace/commandLineSample)
2016-11-01 23:32:46.964 INFO 42306 --- [ main] com.example.AppTest : The following profiles are active: test
2016-11-01 23:32:47.013 INFO 42306 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@a1153bc: startup date [Tue Nov 01 23:32:47 JST 2016]; root of context hierarchy
2016-11-01 23:32:47.178 INFO 42306 --- [ main] com.example.AppTest : Started AppTest in 0.643 seconds (JVM running for 1.686)
2016-11-01 23:32:47.208 INFO 42306 --- [ Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@a1153bc: startup date [Tue Nov 01 23:32:47 JST 2016]; root of context hierarchy
App#runが実行されていないことがわかります。
自分はちょこっとしたコマンドラインアプリでもSpringBootで作ることがあるので、その際には役に立ちそうだなと思っています。
#謝辞
拝啓 本当は Qiita を書きたいのに、まだ迷っているあなたへ。
こちらの記事を見て、小さな発見でも誰かの役に立つかもしれないと考えて、記事を書いてみました。
ありがとうございました。