我写了一个 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 ,但该异常会在上下文初始化期间发生,因此测试甚至无法启动。
答案 0 :(得分:2)
这是我使用的解决方案。我删除了将侦听器手动添加到应用程序的操作,而是使用了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。