问题描述
我使用 JUnit 4 和 spring-test 库编写了一些 JUnit 测试.当我在 Eclipse 中运行测试时,运行良好并通过.但是当我使用 Maven 运行它们时(在构建过程中),它们无法给出与弹簧相关的错误.我不确定是什么导致了这个问题,JUnit、Surefire 还是 Spring.这是我的测试代码、spring 配置和我从 Maven 得到的异常:
PersonServiceTest.java
package com.xyz.person.test;导入静态 com.xyz.person.util.FjUtil.toFjList;导入静态 junit.framework.Assert.assertEquals;导入静态 org.junit.Assert.assertNotNull;导入 java.util.List;导入 org.junit.Test;导入 org.junit.runner.RunWith;导入 org.springframework.beans.factory.annotation.Autowired;导入 org.springframework.test.context.ContextConfiguration;导入 org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;导入 org.springframework.test.context.junit4.SpringJUnit4ClassRunner;导入 org.springframework.test.context.transaction.TransactionConfiguration;导入 org.springframework.transaction.annotation.Transactional;导入 com.xyz.person.bo.Person;导入 com.xyz.person.bs.PersonService;导入 fj.Effect;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = { "classpath*:personservice-test.
personservice-test.
<属性名称=数据源"ref=数据源"/><property name="persistenceUnitName" value="PersonService"/><属性名称="jpaVendorAdapter"><bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"><property name="databasePlatform" value="org.hibernate.dialect.DerbyDialect"/><property name="showSql" value="true"/><property name="generateDdl" value="true"/></bean></属性><属性名称=jpaPropertyMap"><entry key="hibernate.validator.autoregister_listeners" value="false"/><entry key="javax.persistence.transactionType" value="RESOURCE_LOCAL"/></地图></属性></bean><bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"><property name="entityManagerFactory" ref="entityManagerFactory"/><属性名称=数据源"ref=数据源"/></bean><tx:annotation-driven transaction-manager="transactionManager"代理目标类=假"/><bean id="beanMapper" class="org.dozer.DozerBeanMapper"><属性名称=映射文件"><value>personservice-mappings.
Maven 中的异常
-------------------------------------------------------测试-------------------------------------------------------运行 com.xyz.person.test.PersonServiceTest23:18:51,250 警告 JDBCExceptionReporter:77 - SQL 警告:10000,SQLState:01J0123:18:51,281 警告 JDBCExceptionReporter:78 - 未创建数据库InMemoryDatabase",而是连接到现有数据库.23:18:52,937 警告 JDBCExceptionReporter:77 - SQL 警告:10000,SQLState:01J0123:18:52,937 警告 JDBCExceptionReporter:78 - 未创建数据库InMemoryDatabase",而是连接到现有数据库.23:18:52,953 WARN TestContextManager:429 - 在允许 TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener@359a359a] 处理after"执行测试时捕获异常:方法 [public void com.xyz.person.test.PersonServiceTest.testCreatePerson()],实例 [com.xyz.person.test.PersonServiceTest@1bc81bc8],异常 [org.springframework.transaction.IllegalTransactionStateException:预绑定 JDBC 连接找到!如果被告知管理数据源本身,则 JpaTransactionManager 不支持在 DataSourceTransactionManager 中运行.建议对单个 DataSource 上的所有事务使用单个 JpaTransactionManager,无论是 JPA 还是 JDBC 访问.]java.lang.IllegalStateException:绑定到线程 [main] 的键 [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@3f563f56] 没有值在 org.springframework.transaction.support.TransactionSynchronizationManager.unbindResource(TransactionSynchronizationManager.java:199)在 org.springframework.orm.jpa.JpaTransactionManager.doCleanupAfterCompletion(JpaTransactionManager.java:489)在 org.springframework.transaction.support.AbstractPlatformTransactionManager.cleanupAfterCompletion(AbstractPlatformTransactionManager.java:1011)在 org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:804)在 org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)在 org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.endTransaction(TransactionalTestExecutionListener.java:515)在 org.springframework.test.context.transaction.TransactionalTestExecutionListener.endTransaction(TransactionalTestExecutionListener.java:290)在 org.springframework.test.context.transaction.TransactionalTestExecutionListener.afterTestMethod(TransactionalTestExecutionListener.java:183)在 org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:426)在 org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:90)在 org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)在 org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)在 org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)在 org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)在 org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)在 org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)在 org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)在 org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)在 org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)在 org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)在 org.junit.runners.ParentRunner.run(ParentRunner.java:236)在 org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)在 org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:59)在 org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:115)在 org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:102)在 org.apache.maven.surefire.Surefire.run(Surefire.java:180)在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)在 java.lang.reflect.Method.invoke(Method.java:599)在 org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:350)在 org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021)23:18:53,078 WARN TestContextManager:377 - 在允许 TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener@359a359a] 处理测试方法 [public void com.xyz.person.test.] 执行之前"时捕获异常.PersonServiceTest.testFindPersons()] 用于测试实例 [com.xyz.person.test.PersonServiceTest@79f279f2]org.springframework.transaction.IllegalTransactionStateException:找到预绑定的 JDBC 连接!如果被告知管理数据源本身,则 JpaTransactionManager 不支持在 DataSourceTransactionManager 中运行.建议对单个DataSource 上的所有事务使用单个JpaTransactionManager,无论是JPA 还是JDBC 访问.在 org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:304)在 org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371)在 org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.startTransaction(TransactionalTestExecutionListener.java:507)在 org.springframework.test.context.transaction.TransactionalTestExecutionListener.startNewTransaction(TransactionalTestExecutionListener.java:269)在 org.springframework.test.context.transaction.TransactionalTestExecutionListener.beforeTestMethod(TransactionalTestExecutionListener.java:162)在 org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:374)在 org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:73)在 org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)在 org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)在 org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)在 org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)在 org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)在 org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)在 org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)在 org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)在 org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)在 org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)在 org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)在 org.junit.runners.ParentRunner.run(ParentRunner.java:236)在 org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)在 org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:59)在 org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:115)在 org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:102)在 org.apache.maven.surefire.Surefire.run(Surefire.java:180)在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)在 java.lang.reflect.Method.invoke(Method.java:599)在 org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:350)在 org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021)测试运行:3,失败:0,错误:3,跳过:0,经过的时间:15.625 秒<<<失败!结果 :错误测试:testCreatePerson(com.xyz.person.test.PersonServiceTest)testCreatePerson(com.xyz.person.test.PersonServiceTest)testFindPersons(com.xyz.person.test.PersonServiceTest)测试运行:3,失败:0,错误:3,跳过:0
解决方案
我遇到了同样的问题(JUnit 测试在 Maven Surefire 中失败,但在 Eclipse 中通过)并设法通过将 forkMode 设置为总是在 pom.<groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>2.12</version><配置><forkMode>总是</forkMode></配置></插件>
Surefire 参数:http://maven.apache.org/plugins/maven-surefire-plugin/test-mojo.html
编辑(2014 年 1 月):
正如 Peter Perháč 指出的那样,forkMode 参数自 Surefire 2.14 起已弃用.从 Surefire 2.14 开始改用这个:
<groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>2.16</version><配置><reuseForks>false</reuseForks><forkCount>1</forkCount></配置></插件>
更多信息参见Fork 选项和并行测试执行
I have written some JUnit tests using JUnit 4 and spring-test libraries. When I run the tests inside Eclipse then run fine and pass. But when I run them using Maven (during the build process), they fail giving a spring related error. I am not sure what is causing the problem, JUnit, Surefire or Spring. Here is my test code, spring configuration and the exception that I get from Maven:
PersonServiceTest.java
package com.xyz.person.test;
import static com.xyz.person.util.FjUtil.toFjList;
import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.util.List;
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.transaction.annotation.Transactional;
import com.xyz.person.bo.Person;
import com.xyz.person.bs.PersonService;
import fj.Effect;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath*:personservice-test.
personservice-test.
<?
Exception in Maven
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.xyz.person.test.PersonServiceTest
23:18:51,250 WARN JDBCExceptionReporter:77 - SQL Warning: 10000, SQLState: 01J01
23:18:51,281 WARN JDBCExceptionReporter:78 - Database 'InMemoryDatabase' not created, connection made to existing database instead.
23:18:52,937 WARN JDBCExceptionReporter:77 - SQL Warning: 10000, SQLState: 01J01
23:18:52,937 WARN JDBCExceptionReporter:78 - Database 'InMemoryDatabase' not created, connection made to existing database instead.
23:18:52,953 WARN TestContextManager:429 - Caught exception while allowing TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener@359a359a] to process 'after' execution for test: method [public void com.xyz.person.test.PersonServiceTest.testCreatePerson()], instance [com.xyz.person.test.PersonServiceTest@1bc81bc8], exception [org.springframework.transaction.IllegalTransactionStateException: Pre-bound JDBC Connection found! JpaTransactionManager does not support running within DataSourceTransactionManager if told to manage the DataSource itself. It is recommended to use a single JpaTransactionManager for all transactions on a single DataSource, no matter whether JPA or JDBC access.]
java.lang.IllegalStateException: No value for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@3f563f56] bound to thread [main]
at org.springframework.transaction.support.TransactionSynchronizationManager.unbindResource(TransactionSynchronizationManager.java:199)
at org.springframework.orm.jpa.JpaTransactionManager.doCleanupAfterCompletion(JpaTransactionManager.java:489)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.cleanupAfterCompletion(AbstractPlatformTransactionManager.java:1011)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:804)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.endTransaction(TransactionalTestExecutionListener.java:515)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.endTransaction(TransactionalTestExecutionListener.java:290)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.afterTestMethod(TransactionalTestExecutionListener.java:183)
at org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:426)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:90)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:59)
at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:115)
at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:102)
at org.apache.maven.surefire.Surefire.run(Surefire.java:180)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:599)
at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:350)
at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021)
23:18:53,078 WARN TestContextManager:377 - Caught exception while allowing TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener@359a359a] to process 'before' execution of test method [public void com.xyz.person.test.PersonServiceTest.testFindPersons()] for test instance [com.xyz.person.test.PersonServiceTest@79f279f2]
org.springframework.transaction.IllegalTransactionStateException: Pre-bound JDBC Connection found! JpaTransactionManager does not support running within DataSourceTransactionManager if told to manage the DataSource itself. It is recommended to use a single JpaTransactionManager for all transactions on a single DataSource, no matter whether JPA or JDBC access.
at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:304)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.startTransaction(TransactionalTestExecutionListener.java:507)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.startNewTransaction(TransactionalTestExecutionListener.java:269)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.beforeTestMethod(TransactionalTestExecutionListener.java:162)
at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:374)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:73)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:59)
at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:115)
at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:102)
at org.apache.maven.surefire.Surefire.run(Surefire.java:180)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:599)
at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:350)
at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021)
Tests run: 3, Failures: 0, Errors: 3, Skipped: 0, Time elapsed: 15.625 sec <<< FAILURE!
Results :
Tests in error:
testCreatePerson(com.xyz.person.test.PersonServiceTest)
testCreatePerson(com.xyz.person.test.PersonServiceTest)
testFindPersons(com.xyz.person.test.PersonServiceTest)
Tests run: 3, Failures: 0, Errors: 3, Skipped: 0
解决方案
I had the same problem (JUnit tests failed in Maven Surefire but passed in Eclipse) and managed to solve it by setting forkMode to always in the maven surefire configuration in pom.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12</version>
<configuration>
<forkMode>always</forkMode>
</configuration>
</plugin>
Surefire parameters: http://maven.apache.org/plugins/maven-surefire-plugin/test-mojo.html
Edit (January 2014):
As Peter Perháč pointed out, the forkMode parameter is deprecated since Surefire 2.14. Beginning from Surefire 2.14 use this instead:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.16</version>
<configuration>
<reuseForks>false</reuseForks>
<forkCount>1</forkCount>
</configuration>
</plugin>
For more information see Fork Options and Parallel Test Execution
这篇关于JUnit 测试在 Eclipse 中通过但在 Maven Surefire 中失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!