如何在spring-boot应用程序的junit中调用ApplicationContextInitializer
Posted
技术标签:
【中文标题】如何在spring-boot应用程序的junit中调用ApplicationContextInitializer【英文标题】:How to invoke ApplicationContextInitializer in junit of spring-boot application 【发布时间】:2018-07-19 06:21:21 【问题描述】:我是 spring-boot 的新手,并基于squiggly 实现了一个带有动态实体过滤的简单应用程序。一切正常,除了我无法制作一个 junit 来测试该功能。我测试了很多在网上找到的解决方案,但没有一个有效。
我的应用程序已按照 squiggly 文档中的建议进行初始化:
@SpringBootApplication
public class Application
@Bean
public FilterRegistrationBean squigglyRequestFilter()
FilterRegistrationBean filter = new FilterRegistrationBean();
filter.setFilter(new SquigglyRequestFilter());
filter.setOrder(1);
return filter;
public static void main(String[] args)
new MyApplicationContextInitializer().initialize(SpringApplication.run(Application.class, args));
public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext>
@Override
public void initialize(ConfigurableApplicationContext context)
//context.refresh()
Iterable<ObjectMapper> objectMappers = context.getBeansOfType(ObjectMapper.class).values();
Squiggly.init(objectMappers, new RequestSquigglyContextProvider());
ObjectMapper objectMapper = Iterables.getFirst(objectMappers, null);
// Enable Squiggly for Jackson message converter
if (objectMapper != null)
for (MappingJackson2HttpMessageConverter converter : context.getBeansOfType(MappingJackson2HttpMessageConverter.class).values())
converter.setObjectMapper(objectMapper);
这是我实现的测试:
@RunWith(SpringRunner.class)
@SpringBootTest()
@ContextConfiguration(initializers = MyApplicationContextInitializer.class)
@AutoConfigureMockMvc
public class SimpleTest
@Autowired
private MockMvc mockMvc;
@Test
public void testEntityFiltering() throws Exception
this.mockMvc.perform(get("/v1/issues").param("fields", "id"))
.andExpect(status().isOk())
// There should be only one field in the returned objects
.andExpect(jsonPath("$[0].length()").value(1));
当我运行该测试时,我得到以下异常:
java.lang.IllegalStateException: Failed to load ApplicationContext
...
Caused by: java.lang.IllegalStateException: org.springframework.web.context.support.GenericWebApplicationContext@4116aac9 has not been refreshed yet
at org.springframework.context.support.AbstractApplicationContext.assertBeanFactoryActive(AbstractApplicationContext.java:1067) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.getBeansOfType(AbstractApplicationContext.java:1187) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at com.renault.api.examples.springboot.MyApplicationContextInitializer.initialize(MyApplicationContextInitializer.java:28) ~[classes/:na]
at org.springframework.boot.SpringApplication.applyInitializers(SpringApplication.java:567) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.SpringApplication.prepareContext(SpringApplication.java:338) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:301) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:120) ~[spring-boot-test-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98) ~[spring-test-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116) ~[spring-test-4.3.13.RELEASE.jar:4.3.13.RELEASE]
... 25 common frames omitted
如果我取消注释 MyApplicationContextInitializer.initialize 中的 //context.refresh 行,我会收到以下异常:
java.lang.IllegalStateException: Failed to load ApplicationContext
...
Caused by: java.lang.IllegalStateException: GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once
at org.springframework.context.support.GenericApplicationContext.refreshBeanFactory(GenericApplicationContext.java:263) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:614) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:515) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:120) ~[spring-boot-test-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98) ~[spring-test-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116) ~[spring-test-4.3.13.RELEASE.jar:4.3.13.RELEASE]
... 25 common frames omitted
如果去掉@ContextConfiguration注解,测试失败,因为没有安装实体过滤器。
看来 *** 是我完成这项工作的最后机会......
【问题讨论】:
【参考方案1】:有点晚了,但你可以尝试将 context.initializer.classes=your.package.MyApplicationContextInitializer 放在 src/test/resources/application.properties 中
【讨论】:
对我没有帮助。以上是关于如何在spring-boot应用程序的junit中调用ApplicationContextInitializer的主要内容,如果未能解决你的问题,请参考以下文章
如何使用junit在spring-boot中测试常见错误ErrorController
Spring-boot,使用不同配置文件的 JUnit 测试