我想使用spring MockMVC工具编写集成测试:
MockMvcBuilders.webAppContextSetup(...).build();
阅读可用文档http://docs.spring.io/spring/docs/current/spring-framework-reference/html/testing.html#spring-mvc-test-framework只留下一个问题:如何为以编程方式创建的WebApplicationContext设置测试?
如果我正确理解了模拟mvc测试的想法,它会神奇地发现一个包含调度程序servlet和用于安装的WebApplicationContext的servlet上下文。目前,我手动创建WebApplicationContext并将DispatcherServlet添加到jetty实例。我想我必须以某种方式解耦?
我想使用SpringWebConfiguration.class中定义的Web上下文并模拟SpringConfiguration.class中定义的根上下文中的所有内容
public static void main(String[] args) throws Exception {
SimpleCommandLinePropertySource ps = new SimpleCommandLinePropertySource(args);
ApplicationContext rootContext = createRootContext(ps);
//start jetty
Server server = new Server(Integer.parseInt(ps.getProperty("port")));
ServletContextHandler contextHandler = new ServletContextHandler();
contextHandler.setContextPath("/");
createWebContext(rootContext, contextHandler);
server.setHandler(contextHandler);
server.start();
server.join();
}
private static ApplicationContext createRootContext(PropertySource propertySource) {
AnnotationConfigApplicationContext rootContext = new AnnotationConfigApplicationContext();
rootContext.getEnvironment().getPropertySources().addFirst(propertySource);
rootContext.register(SpringConfiguration.class); //main configuration class for all beans
rootContext.refresh();
return rootContext;
}
public static WebApplicationContext createWebContext(ApplicationContext rootContext) {
AnnotationConfigWebApplicationContext webApplicationContext = new AnnotationConfigWebApplicationContext();
webApplicationContext.setParent(rootContext);
webApplicationContext.register(SpringWebConfiguration.class);
return webApplicationContext;
}
private static WebApplicationContext createWebContext(ApplicationContext rootContext, ServletContextHandler servletContext) throws ServletException {
WebApplicationContext webApplicationContext = createWebContext(rootContext);
/* enable logging of each http request */
servletContext.addFilter(LoggingFilterChain.class, "/*", EnumSet.of(DispatcherType.REQUEST));
registerDispatcherServlet("api", servletContext, webApplicationContext);
return webApplicationContext;
}
private static DispatcherServlet registerDispatcherServlet(String path, ServletContextHandler servletContext, WebApplicationContext ctx) {
DispatcherServlet servlet = new DispatcherServlet(ctx);
servletContext.addServlet(new ServletHolder(servlet), "/" + path + "/*");
return servlet;
}
我知道如何更改配置才能使用mockmvc测试吗?我更喜欢没有spring.xml / web.xml的解决方案。
答案 0 :(得分:0)
可悲的是没有答案,但过了一段时间我得到了Spring开发人员的意图以及servlet上下文如何工作:
在我使用jetty启动具有特定上下文的某个DispatcherServlet的问题中。没有魔法,很清楚会发生什么。没办法在两者之间嘲笑。为了将servlet容器(jetty)与实际的Web应用程序上下文分开,我必须:
使用spring WebApplicationInitializer接口并在那里配置上下文
让码头找到背景。这部分有点棘手,因为我的jetty版本只扫描jar文件,所以我决定将我的码头强烈地与我的网络应用程序结合起来会更好:
-
WebAppContext webAppContext = new WebAppContext();
webAppContext.setConfigurations(new Configuration[]{new ConcreteConfiguration(ServletInitializer.class)}); //that class implements the WebApplicationInitializer of spring.
//...
/**
* Configures a concrete WebApplicationInitializer
*/
static class ConcreteConfiguration extends AnnotationConfiguration {
private final Class<?> initializerClass;
ConcreteConfiguration(Class<?> initializerClass) {
this.initializerClass = initializerClass;
}
@Override
public void preConfigure(WebAppContext context) throws Exception {
MultiMap<String> map = new MultiMap<String>();
map.add(WebApplicationInitializer.class.getName(), initializerClass.getName());
context.setAttribute(CLASS_INHERITANCE_MAP, map);
_classInheritanceHandler = new ClassInheritanceHandler(map);
}
}
(我在这里找到了静态内部类的想法:https://stackoverflow.com/a/15702616/320299)