【问题标题】:SpringBootTest - how to assert if context loading failsSpringBootTest - 如果上下文加载失败如何断言
【发布时间】:2019-06-03 14:31:39
【问题描述】:

我写了一个ApplicationListener,它应该检查环境是否在上下文初始化期间准备好。我在测试场景时遇到了麻烦,因为我在 configure()main() 方法中都手动添加了侦听器。

ApplicationListener 类:

public class EnvironmentPrepared implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {

        @Override
    public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
            //code that checks if conditions are met

            if (checkTrue) {
            throw new RuntimeException();
        }
    }
}

主类:

    public class MyApp extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        setRegisterErrorPageFilter(false);
        return application.listeners(new EnvironmentPrepared()).sources(MyApp.class);
    }

    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(MyApp.class);
        springApplication.addListeners(new EnvironmentPrepared());
        springApplication.run(args);
    }
}

我要执行的测试:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ContextConfiguration(loader = OverriddenProfilesTest.CustomLoader.class)
public class OverriddenProfilesTest {

    public static class CustomLoader extends SpringBootContextLoader {

        @Override
        protected SpringApplication getSpringApplication() {
            SpringApplication app = super.getSpringApplication();
            app.addListeners(new EnvironmentPrepared());
            return app;
        }
    }

    /**
     * Checks if spring can bootstrap everything 
     */
    @Test(expected = RuntimeException.class)
    public void test() {

    }
}

这将是我想要的测试。 RuntimeException 被抛出,但异常发生在上下文初始化期间,因此测试甚至没有开始。

【问题讨论】:

  • 你可以尝试在你的测试方法中以编程方式加载它,检查AbstractApplicationContext的层次结构,对于xml配置例如:ApplicationContext applicationContext = new ClassPathXmlApplicationContext("my-app-context.xml");
  • 感谢您的输入,我已经使用 AbstractRefreshableApplicationContext 进行了尝试,但没有达到我的预期。在我看来,通常创建另一个上下文会产生更多问题。您可以查看我在下面使用的解决方案...

标签: spring-boot integration-testing listener spring-boot-test


【解决方案1】:

这是我使用的解决方案。我删除了手动将监听器添加到应用程序并改用 spring.factories 文件。

关于测试,我首先创建了一个自定义运行器类:

    public class SpringRunnerWithExpectedExceptionRule extends SpringJUnit4ClassRunner {

public SpringRunnerWithExpectedExceptionRule(Class<?> clazz) throws InitializationError {
    super(clazz);
}

@Override
protected Statement methodBlock(FrameworkMethod frameworkMethod) {
    List<ExpectedException> testRules = getTestClass().getAnnotatedFieldValues(null, ExpectedExceptionClassRule.class, ExpectedException.class);
    Statement result = super.methodBlock(frameworkMethod);
    for (TestRule item : testRules) {
        result = item.apply(result, getDescription());
    }
    return result;
}}

然后我创建以下注释:

@Retention(RUNTIME)
@Target({ FIELD })
public @interface ExpectedExceptionClassRule {

}

最后,我能够用我的跑步者运行测试:

@RunWith(SpringRunnerWithExpectedExceptionRule.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class OverriddenProfilesTest {

    @ExpectedExceptionClassRule
    public static ExpectedException expectedException = ExpectedException.none();

    @BeforeClass
    public static void before() {
        expectedException.expectCause(runtimeExceptionMethod());
    }


    @Test
    public void testThatShouldThrowExceptionWhileSettingContext {
    }

    static Matcher<Throwable> runtimeExceptionMethod() {
        return new IsRuntimeException();
    }

    static class IsRuntimeException extends TypeSafeMatcher<Throwable> {
    //do stuff
    }

有关解决方案的更多信息,请参阅here

【讨论】:

    猜你喜欢
    • 2019-06-14
    • 1970-01-01
    • 1970-01-01
    • 2019-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多