公司这个项目,不是我来配置构建的, 把 spring的配置什么的,和 springmvc的配置没有区分开来,都是在一个配置文件里面,也就是 springmvc 里面。 和咱们通常的 配置不同,咱们通常配置都是 配置好 spring 容器的,,而后配置好 springmvc 的分开来。 但是 这个项目不是这样的,,,感受是有点乱,后期也难维护管理。。。java
没办法了。 这个项目,他们是没有 junit 的, 估计他们不喜欢用吧。 但是我是有点喜欢junit 测试的。 因此想本身集成junit ,在写代码的时候,方便本身测试使用。web
但是在集成的时候 junit的时候 竟然报错了。。。spring
java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:99) at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:122) at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109) at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75) at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:312) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:284) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:539) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:761) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:461) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:207) Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'initService' defined in file [D:\SVN\rpd-p2p\branches\1.3.1.shortcutpay\rpd-p2p\build\classes\com\moneyP2P\p2p\VSFP\spring\service\InitService.class]: Initialization of bean failed; nested exception is java.lang.ClassCastException: org.springframework.context.support.GenericApplicationContext cannot be cast to org.springframework.web.context.WebApplicationContext at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:529) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:628) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479) at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:120) at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60) at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:100) at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:248) at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContextInternal(CacheAwareContextLoaderDelegate.java:64) at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:91) ... 25 more Caused by: java.lang.ClassCastException: org.springframework.context.support.GenericApplicationContext cannot be cast to org.springframework.web.context.WebApplicationContext at com.moneyP2P.p2p.VSFP.spring.service.InitService.setApplicationContext(InitService.java:251) at org.springframework.context.support.ApplicationContextAwareProcessor.invokeAwareInterfaces(ApplicationContextAwareProcessor.java:117) at org.springframework.context.support.ApplicationContextAwareProcessor.postProcessBeforeInitialization(ApplicationContextAwareProcessor.java:92) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:396) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1505) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521) ... 39 more
什么意思啊。。。? 百度一下,,,发现这样的问题实在是太少了。。。 使用网上的办法发现也不行啊。 我一点点看的时候,发现是在 某个 service 类初始化的时候,报错了。 这个 service implements ApplicationContextAware 这类。 按理来讲,应该能够获取到啊,和 junit测试看起来是没有问题的。。 继续看报错信息,说是某一些报错了spring-mvc
@Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { ServletContext application = ((WebApplicationContext) applicationContext) .getServletContext(); application.setAttribute( WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, applicationContext); columnServic.queryAllTopics(application); application.setAttribute("application_link", linkService.query()); application.setAttribute("application_banner", bannerService.query()); //页面底部信息 application.setAttribute("footer", footerservice.queryFooter()); //页面系统信息 application.setAttribute("sysconfig", syscfgService.getSysConfig()); initEnumStatus(application); initSetSafetyQuestion(application); initSetServiceUser(application); }
看到了? 这里 是 WebApplicationContext , 和web相关要拿到 servlet 容器相关的。 咱们通常都是 直接获取 ApplicationContext 就能够了。 而个人junit 测试,只是想 测试 spring的 service 而已,并非 controller 类。 可是这里是 要获取 WebApplicationContext 类的,因此执行 junit 初始化的时候获取不到就报错了。 而且也试过在 junit 测试的以前,构建 WebApplicationContext ,结果也是不行的。mvc
所以只能 使用 junit的 web测试 方式来了,这样应该就能够了。 构建来了以后果真能够了。 下面是个人 junit spring mvc 测试类app
package com.mytest.junit; 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.AbstractTransactionalJUnit4SpringContextTests; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.transaction.TransactionConfiguration; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import com.moneyP2P.p2p.VSFP.spring.controller.test.MyTestController; import com.moneyP2P.p2p.VSFP.spring.service.UserBaseInfoService; @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration(locations = "classpath*:config/main/spring-mvc.xml") // 默认不回滚, 若是须要 回滚,请本身 在方法 加上 回滚, @Rollback(true) 或者是 defaultRollback = true @TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false) // extends AbstractTransactionalJUnit4SpringContextTests public class MyJunitTest extends AbstractTransactionalJUnit4SpringContextTests { // @Autowired // private WebApplicationContext wac; @Autowired private MyTestController myTestController; private MockMvc mockMvc; @Autowired private UserBaseInfoService userBaseInfoService; @Before public void setup() { // 模拟web必须有这个 构建代码不然报错 mockMvc = MockMvcBuilders.standaloneSetup(myTestController).build(); } @Test public void test() { System.out.println("=="); System.out.println(userBaseInfoService.queryUserById(113L).getUserName()); } }
这样咱们写 test 方法的时候,直接就获取 spring 的bean 来测试了,或者说想 mockMVC 使用 controller 来测试 也是能够的。eclipse
@RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration(locations = { "classpath:applicationContext-core.xml", "classpath:applicationContext-servlet.xml" }) public class TestController { @Autowired private WebApplicationContext wac; @Autowired private SYSUserController userController;//你要测试的Controller private MockMvc mockMvc; @Before public void setup() { mockMvc = MockMvcBuilders.standaloneSetup(userController).build(); } @Test public void testFindPageUsers() throws Exception { ResultActions ra = this.mockMvc.perform(MockMvcRequestBuilders .post("/sysconfig/user/findPageUsers") .accept(MediaType.APPLICATION_JSON).param("page", "1") .param("limit", "10")); MvcResult mr = ra.andReturn(); String result = mr.getResponse().getContentAsString(); log.info(result); } }