junit能否启动web项目设置的web listener?

来源:互联网 发布:淘宝店铺免费一键复制 编辑:程序博客网 时间:2024/05/20 05:31

项目里边的开发遇到一个问题:
一个spring mvc的项目,无法进行junit测试,说调试了很久都不行。作为一个测试开发,我表示这个跟吃菜一样简单,于是我就兴冲冲的跳进了这个坑里边

我想,junit测试controller这种东西网上一搜一大把,果断先来一发ctrl c+ctrl v。类似下边的代码看起来是不是相当的熟悉?

package com.junitDemo.controller.mobile;  import org.junit.Before;  import org.junit.Test;  import org.junit.runner.RunWith;  import org.springframework.beans.factory.annotation.Autowired;  import org.springframework.test.context.ContextConfiguration;  import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;  import org.springframework.test.web.servlet.MockMvc;  import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;  import org.springframework.test.web.servlet.result.MockMvcResultHandlers;  import org.springframework.test.web.servlet.result.MockMvcResultMatchers;  import org.springframework.test.web.servlet.setup.MockMvcBuilders;  @RunWith(SpringJUnit4ClassRunner.class)  @ContextConfiguration(locations = { "classpath:applicationContext.xml","classpath:servlet-context.xml"})  public class IndexControllerTest {      private MockMvc mockMvc;      @Autowired      private IndexController indexController;      @Before      public void setUp() throws Exception {           mockMvc = MockMvcBuilders.standaloneSetup(indexController).build();      }      /**      * 主页      */      @Test      public void testIndex() throws Exception {          mockMvc.perform(MockMvcRequestBuilders.get("/index.html"))                  .andExpect(MockMvcResultMatchers.view().name("/index"))                  .andReturn();      }  }  

这个是我从网上直接copy过来的。一运行,果然遇到了第一个坑:
java.lang.NoSuchMethodError: org.springframework.core.annotation.AnnotatedE

百度了一番,这个是spring-test的包跟spring-core的版本冲突,但是我认真的检查了项目的pom文件,spring-test跟spring-core的版本是一致的。
这下我回过味来了,这个开发不厚道啊。这是让我填坑哪,不过无所谓,既然接了,硬着头皮也要搞,不能就这么放弃。

转念一想,有没有可能是其他的jar包,需要用低版本的spring-core呢?属于隐藏的依赖?(其实这想法是真的蠢,如果有,maven早自动关联进来了,maven depencies就能看出来,没办法,我当时有点激动)
顺势去百度了一哈,找了个方法,如何打印出项目所有的依赖
http://maven.apache.org/plugins/maven-dependency-plugin/examples/resolving-conflicts-using-the-dependency-tree.html

果然too young,确实没有这个问题。哎不对,这个project是有parent project管理整体的依赖的。
果断去parent project运行了一把。原来parent project,引入了低版本的spring-test,实际在子项目
生效的,就是低版本的。。泪目,我一个测试如何知道你们这么多套路。。

好吧,立马改掉。兴奋的重新运行,期待这熟悉的绿色toolbar。。

然而,现实哪里有这么简单。
这会直接报无法load applicationContext 原因是${root_class_path}无法识别。。
这简单啊。这开发干啥子吃的,我直接找到这个文件,改成了file:src/main/resource/xxx.xml的形式
继续启动,就不信你不行……

现实总是很残酷,会一直打击你,这会又是duang的一声,failed to load applicatContext
这次是${dbSchema}无法识别

我怒了,直接搜索所有的配置文件,看看是不是placeholder没写好。找了一圈,都没找到。这哥们有点不按套路出牌啊,如果这样,他tomcat怎么启动能成功的

不行直接使用终极武器。。全文件搜索,终于找到这个的初始化了,原来他写了个自定义的ServletContext listener,在start里边,初始化了这个值。System.setProperty(“dbSchema”,”public”);连上边的root_class_path也是这么初始话的
。。有点郁闷,那为啥junit的runwith跟configuration不能直接启动呢?

查了一番资料发现:
TOMCAT的启动顺序:context-param -> listener -> filter -> servlet(application-context)
junit配合spring-test,直接就启动application-context,他写的那个变量的初始化根本就没加载进内存.

好家伙,隐藏的这么深。这下总能搞定你了吧

现实是真的很残酷,我百度,翻墙google。。。都没有找到解决方案。无法使用junit启动listener。就连死马当活马医,在 @before里边,写dbSchema的初始化,都没用。因为在before前,就已经在load application-context。。

所以回到题目的问题,能不能使用junit启动呢?答案是不能。

那这一天的活是不是白干了呢?倒也不是。
起码学到了一些东西:
1、maven -depency:tree 解决包冲突
2、parent project,project管理的一些概念
3、spring启动 的时候,查找变量的顺序context-param、配置文件配置好的place-holder的key-value,还有系统runtime的property
4、tomcat启动各个组件的顺序context-param -> listener -> filter -> servlet

虽然,最终的结果是,无法使用junit来测试这个项目。但是起码也得到了一些知识跟练习。也算是小小的成长。

1 0
原创粉丝点击