公司這個項目,不是我來配置構建的, 把 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); } }