JUnit Test in Spring Context with JNDI Data Source
2013-06-09 19:22
471 查看
Trigger: SpringJUnit4ClassRunner Failed to load ApplicationContext
Quote: When you run your testcases, you will want to use JDBC instead of JNDI lookup. The simple reason is because you usually don't run your testcases from the application server. Thus, JNDI lookup will fail.
then I realized that JNDI configuration caused my problem and I had to pay more attention to the application context configuration if I want to perform JUnit test in spring. Unfortunately, I don't think the above post's separate application context files solution
is elegant enough.
Solution Suits Me
After some homework, I find this solution fits me well:
(1) Employ the profile feature since spring framework 3.1;
(2) Base on (1), apply nested <beans/> elements;
Thereby, we don't have to split application context file into multiple files, and it's unnecessary to import resource now.
Reference:
1. http://stackoverflow.com/questions/5197236/spring-jndi-configuration-problem
2. http://blog.springsource.com/2011/02/11/spring-framework-3-1-m1-released/
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.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:105) at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:74) 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:15) 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:231) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222) 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:300) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in URL [file:/D:/eclipse_workspace/bank-api/target/classes/spring.xml]: Invocation of init method failed; nested exception is javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initialI didn't know since when my unit tests were unable to run, all tests with SpringJUnit4ClassRunner Failed to load ApplicationContext. I googled this error but didn't find a clue until I hit this post: reference 1,
Quote: When you run your testcases, you will want to use JDBC instead of JNDI lookup. The simple reason is because you usually don't run your testcases from the application server. Thus, JNDI lookup will fail.
then I realized that JNDI configuration caused my problem and I had to pay more attention to the application context configuration if I want to perform JUnit test in spring. Unfortunately, I don't think the above post's separate application context files solution
is elegant enough.
Solution Suits Me
After some homework, I find this solution fits me well:
(1) Employ the profile feature since spring framework 3.1;
(2) Base on (1), apply nested <beans/> elements;
Thereby, we don't have to split application context file into multiple files, and it's unnecessary to import resource now.
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation="..."> <bean id="transferService" class="com.bank.service.internal.DefaultTransferService"> <constructor-arg ref="accountRepository"/> <constructor-arg ref="feePolicy"/> </bean> <bean id="accountRepository" class="com.bank.repository.internal.JdbcAccountRepository"> <constructor-arg ref="dataSource"/> </bean> <bean id="feePolicy" class="com.bank.service.internal.ZeroFeePolicy"/> <beans profile="test"> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" p:driverClassName="com.mysql.jdbc.Driver" p:url="jdbc:mysql://10.0.2.53:3306/banker" p:username="root" p:password="#$asd123" /> </beans> <beans profile="production"> <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/banker" expected-type="javax.sql.DataSource" /> </beans> </beans>(3) Update web.xml
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring.xml</param-value> </context-param> <context-param> <param-name>spring.profiles.active</param-name> <param-value>production</param-value> </context-param> <servlet> <servlet-name>spring</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:servlet-context.xml </param-value> </init-param> </servlet>(4) Use @ActiveProfiles("test") annotation in JUnit Test
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath*:spring.xml") @ActiveProfiles("test") public class CheckStatusTest { @Autowired private ICheckStatusService checkStatusService; @Test public void testCheckStatus() { //Test Code } }Now, the unit tests run smoothly without any ugly code or configuration!
Reference:
1. http://stackoverflow.com/questions/5197236/spring-jndi-configuration-problem
2. http://blog.springsource.com/2011/02/11/spring-framework-3-1-m1-released/
相关文章推荐
- JUnit Test in Spring Context with JNDI Data Source
- SPRING IN ACTION 第4版笔记-第十一章Persisting data with object-relational mapping-002设置JPA的EntityManagerFactory(<persistence-unit>、<jee:jndi-lookup>)
- 错误:严重: Servlet.service() for servlet [appServlet] in context with path [] threw exception [Request processing failed; nested exception is org.mybatis.spring.MyBatisSystemException: nested exception is
- Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test java.lang.IllegalStateException
- java类中导入@Test单元测试注解报错:The import org.junit.Test conflicts with a type defined in the same file
- spring.data.jpa.query :Cannot use native queries with dynamic sorting and/or pagination in method
- SPRING IN ACTION 第4版笔记-第十一章Persisting data with object-relational mapping-003编写JPA-based repository( @PersistenceUnit、 @PersistenceContext、PersistenceAnnotationBeanPostProcessor)
- The import org.junit.Test conflicts with a type defined in the same file报错
- JUnit integration test with Spring
- JUnit custom runner with Spring application context
- 警告: No mapping found for HTTP request with URI [/Springmvc/test] in DispatcherServlet with dispatche
- *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit
- Servlet.service() for servlet [spring] in context with path [] threw exception [Request processing f
- SPRING IN ACTION 第4版笔记-第十一章Persisting data with object-relational mapping-006Spring-Data的运行规则(@EnableJpaRepositories、<jpa:repositories>)
- Spring加载Hibernate失败:Error creating bean with name 'sessionFactory' defined in ServletContext... Null
- *** Assertion failure in -[UISectionRowData refreshWithSection:tableView:tableViewRowData:], /Source
- Spring TestContext 做带事务回滚的JUnit测试
- Spring异常:Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF
- Bug--Error creating bean with name 'sessionFactory' defined in class path resource [data_context.xml
- Performance Comparison Studies With Real-Life Scenarios in an Experimental Data Taking Context Lever