需要能够在单元测试中捕获 Spring 启动异常

Posted

技术标签:

【中文标题】需要能够在单元测试中捕获 Spring 启动异常【英文标题】:Need to be able to catch Spring startup exception in unit test 【发布时间】:2015-04-29 09:55:11 【问题描述】:

我有一种情况,我们想在启动时检查 Spring MVC 代码并在不满足某些条件时抛出异常(从而导致 ApplicationContext 失败)。

有没有办法检测 JUnit 测试来捕获 Spring 启动(特别是在大多数情况下是 Spring Boot)异常,以便它们不会导致测试失败?如果异常没有发生,我基本上希望测试失败。

【问题讨论】:

将在测试方法中使用您的 beans xml 描述以编程方式初始化 Spring,并使用 @Test(expected=SomeException.class) 注释该方法,是吗? 或者使用@Rule ExpectedException 甚至更好:blog.codeleak.pl/2014/03/… @Victor Sorokin,我不确定这是否可行。我目前正在注释我的单元测试:@RunWIth(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = MyApplicationObjects.class) // this one has the controller i want to test @WebAppConfiguration 恐怕这会为所有测试方法初始化一次 Spring 应用程序。我一定会去看看的。 【参考方案1】:

在您的 JUnit 测试中,您可以通过编程方式启动您的 Spring Boot 应用程序 - 类似于您的 Application 类的 main() 方法。在这样的测试中,您可以像往常一样断言异常。

  @Test
  public void test() 
    SpringApplication springApplication = new SpringApplication(MySpringBootApp.class);
    // Here you can manipulate the app's Environment, Initializers etc.     

    assertThatThrownBy(() -> 
      springApplication.run();
    ).isInstanceOf(Exception.class);
  

【讨论】:

【参考方案2】:

我昨天能够解决问题。因为默认的SmartContextLoader 类如AnnotationConfigWebContextLoaderSpringApplicationContextLoader 是由注释拉入的,完全加载了ApplicationContext,所以我无法捕获那里的任何异常。

我想出的解决方案——我敢肯定还有更优雅的解决方案——是创建我自己的SmartContextLoader 实现,它将所有内容委托给AnnotationConfigWebContextLoader,除了loadContext 方法.在那里,除了刷新WebApplicationContext,我做了所有事情。然后,在我的测试方法中,我手动构建并运行了SpringBootApplication,它将保存我的测试控制器(以及无效的配置)。

感谢@viktor-sorokin 和@grzesuav 让我走上了正确的道路。

【讨论】:

以上是关于需要能够在单元测试中捕获 Spring 启动异常的主要内容,如果未能解决你的问题,请参考以下文章

测试开发专题:spring-boot自定义异常返回

测试开发专题:spring-boot自定义异常返回

python单元测试中的assertRaises没有捕获异常[重复]

如何使用 power mock 对 Spring Boot Rest 控制器和异常处理程序进行单元测试

springboot 单元测试(如何使用基于web的单元测试?)

求助,spring-boot升级带来的异常