Spring命令行应用集成测试问题:无法断言方法行为
问题分析与解决方案
你的问题根源在于:应用实现了CommandLineRunner,其run方法中直接调用了System.exit(),导致Spring Boot测试上下文刚启动就触发JVM终止,测试方法还没机会执行断言逻辑。
解决步骤
1. 改造应用代码,增加退出控制
修改MyApplication的run方法,通过配置属性控制是否执行System.exit(),避免测试环境下自动退出:
@SpringBootApplication public class MyApplication implements CommandLineRunner { @Autowired ApplicationContext applicationContext; @Autowired MyService service; // 通过配置属性控制是否退出 @Value("${app.exit-on-complete:true}") private boolean exitOnComplete; public static void main(final String[] args) { SpringApplication.run(MyApplication.class, args); } @Override public void run(String... args) throws Exception { int exitCode = service.run(); // 仅在生产环境执行退出逻辑 if (exitOnComplete) { System.exit(SpringApplication.exit(applicationContext, () -> exitCode)); } } }
2. 在测试类中覆盖配置,禁用自动退出
在测试类中通过@SpringBootTest的properties属性覆盖配置,阻止应用退出,同时验证MyService的调用:
import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import static org.mockito.Mockito.verify; @SpringBootTest(properties = "app.exit-on-complete=false") public class MyIntTest { @MockBean MyService service; @Test void shouldCallServiceRunMethod() { // 验证service.run()被调用 verify(service).run(); } }
备选方案:手动触发CommandLineRunner逻辑
如果不想修改应用代码,也可以在测试类中手动调用CommandLineRunner的run方法,控制执行时机:
import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import static org.mockito.Mockito.verify; @SpringBootTest public class MyIntTest { @MockBean MyService service; @Autowired MyApplication myApplication; @Test void shouldCallServiceRunMethod() throws Exception { // 手动触发run方法 myApplication.run(); // 验证service调用 verify(service).run(); } }
内容的提问来源于stack exchange,提问作者Patan
相关产品推荐
相关产品推荐

