Eclipse中的JUnittesting通过,但在Maven Surefire中失败

我已经使用JUnit 4和spring-test库编写了一些JUnittesting。 当我在Eclipse中运行testing,然后运行正常,并通过。 但是,当我使用Maven(在构build过程中)运行它们时,它们失败,从而导致与弹簧相关的错误。 我不确定是什么导致了这个问题,JUnit,Surefire或Spring。 这里是我的testing代码,弹簧configuration和我从Maven得到的exception:

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.xml" }) @TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false) public class PersonServiceTest { @Autowired private PersonService service; @Test @Transactional public void testCreatePerson() { Person person = new Person(); person.setName("abhinav"); service.createPerson(person); assertNotNull(person.getId()); } @Test @Transactional public void testFindPersons() { Person person = new Person(); person.setName("abhinav"); service.createPerson(person); List<Person> persons = service.findPersons("abhinav"); toFjList(persons).foreach(new Effect<Person>() { public void e(final Person p) { assertEquals("abhinav", p.getName()); }}); } } 

personservice-的test.xml

 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <import resource="classpath:/personservice.xml" /> <bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" lazy-init="true"> <property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver" /> <property name="url" value="jdbc:derby:InMemoryDatabase;create=true" /> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="datasource" /> <property name="persistenceUnitName" value="PersonService" /> <property name="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> </property> <property name="jpaPropertyMap"> <map> <entry key="hibernate.validator.autoregister_listeners" value="false" /> <entry key="javax.persistence.transactionType" value="RESOURCE_LOCAL" /> </map> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> <property name="dataSource" ref="datasource" /> </bean> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="false" /> <bean id="beanMapper" class="org.dozer.DozerBeanMapper"> <property name="mappingFiles"> <list> <value>personservice-mappings.xml</value> </list> </property> </bean> </beans> 

Maven中的例外

 ------------------------------------------------------- TESTS ------------------------------------------------------- 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 

我有同样的问题(JUnittesting在Maven Surefire中失败,但在Eclipse中传递),并通过设置forkMode 始终在pom.xml中maven surefireconfiguration中设法解决:

 <插件>
     <的groupId> org.apache.maven.plugins </的groupId>
     <artifactId的>行家-万无一失-插件</ artifactId的>
     <版本> 2.12 </版本>
     <结构>
         <forkMode>总是</ forkMode>
     </configuration>
 </插件>

Surefire参数: http : //maven.apache.org/plugins/maven-surefire-plugin/test-mojo.html

编辑(2014年1月):

正如PeterPerháč指出的那样,自从Surefire 2.14以来,forkMode参数已经被弃用了。 从Surefire 2.14开始,改用这个:

 <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> 

有关更多信息,请参阅分叉选项和并行testing执行

我突然遇到这个错误,对我来说解决scheme是禁用并行运行testing。

你的milage可能会有所不同,因为我可以通过configurationsurefire以“classes”方式运行并行testing来减less失败的testing次数。

  <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.7.2</version> <configuration> <parallel>classes</parallel> <threadCount>10</threadCount> </configuration> </plugin> 

正如我写的第一个,这是不够我的testing套件,所以我完全禁用并行通过删除<configuration>部分。

我有一个类似的问题,testing代码中的注释@Autowired在使用Maven命令行时无法正常工作,而在Eclipse中正常工作。 我只是将我的JUnit版本从4.4更新到4.9,问题就解决了。

 <dependency> <groupId>junit</groupId <artifactId>junit</artifactId> <version>4.9</version> </dependency> 

我有类似的问题,但用IntelliJ IDEA + Maven + TestNG + spring-test。 (当然, 弹簧testing是必不可less的:))当我更改maven-surefire-plugin的configuration以并行禁用运行testing时,它已经修复。 喜欢这个:

 <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.9</version> <configuration> <skipTests>${maven.test.skip}</skipTests> <trimStackTrace>false</trimStackTrace> <!--<parallel>methods</parallel>--> <!-- to skip integration tests --> <excludes> <exclude>**/IT*Test.java</exclude> <exclude>**/integration/*Test.java</exclude> </excludes> </configuration> <executions> <execution> <id>integration-test</id> <phase>integration-test</phase> <goals> <goal>test</goal> </goals> <configuration> <skipTests>${maven.integration-test.skip}</skipTests> <!-- Make sure to include this part, since otherwise it is excluding Integration tests --> <excludes> <exclude>none</exclude> </excludes> <includes> <include>**/IT*Test.java</include> <include>**/integration/*Test.java</include> </includes> </configuration> </execution> </executions> </plugin> 

这并不完全适用于你的情况,但我也有同样的事情 – 当Maven的testing目标运行时,通过Eclipse的testing失败。

事实certificate,在我的套件早些时候, 在一个不同的包 。 这花了我一个星期解决!

一个较早的testing是testing一些Logback类,并从configuration文件创build一个Logback上下文。

后来的testing是testingSpring的SimpleRestTemplate的一个子类,不知何故,早先的Logback上下文被保留,DEBUG打开。 这导致在RestTemplate中进行额外的调用来loggingHttpStatus等。

检查是否有人遇到这种情况是另一回事。 我通过在我的Logbacktesting类中注入了一些Mock来解决了我的问题,所以没有创build真正的Logback上下文。

我有同样的问题,但我的问题是,Java断言(例如断言(num> 0))没有启用的Eclipse,但启用时运行maven。

因此,从Eclipse运行jUnittesting没有捕获触发断言错误。

当使用jUnit 4.11(与我使用的旧版本相反)时,这是明确的,因为它打印出断言错误,例如

 java.lang.AssertionError: null at com.company.sdk.components.schema.views.impl.InputViewHandler.<init>(InputViewHandler.java:26) at test.com.company.sdk.util.TestSchemaExtractor$MockInputViewHandler.<init>(TestSchemaExtractor.java:31) at test.com.company.sdk.util.TestSchemaExtractor.testCreateViewToFieldsMap(TestSchemaExtractor.java:48) 

[我不确定这是否是对原始问题的回答,因为这里的堆栈跟踪看起来有些不同,但对其他人可能有用。]

您也可以在运行Cobertura时获得Surefiretesting失败(获取代码覆盖率报告)。 这是因为Cobertura需要代理(来衡量代码的使用),并且这些代理和Spring代理之间有某种冲突。 这只有在Spring使用cglib2时才会发生,例如,如果您有proxy-target-class="true" ,或者您有一个正在被代理的对象没有实现接口,则会发生这种情况。

正常的解决方法是添加一个接口。 所以,例如,DAO应该是由DAOImpl类实现的接口。 如果你在界面上自动assembly,一切都会正常工作(因为不再需要cglib2;可以使用更简单的JDK代理接口,而Cobertura可以正常工作)。

但是,你不能使用具有注释控制器的接口(当你尝试在一个servlet中使用控制器的时候你会得到一个运行时错误) – 我没有一个Cobertura + Spring自动testing控制器的解决scheme。

我今天遇到了这个问题,testing了一个将包含Map的对象转换为JSONstring的方法。 我认为Eclipse和Maven surefire插件使用了不同的JRE,这些JRE具有不同的HashMapsorting实现或者其他的东西,这导致通过Eclipse运行的testing通过,testing通过surefire运行失败( assertEquals失败)。 最简单的解决scheme是使用具有可靠sorting的Map的实现。

我有一个类似的问题:在Maven Surefire中,JUnittesting失败,但是当我使用SpringSource Bundle Repository中的JUnit库版本4.11.0时,它在Eclipse中传递。 格外:

 <dependency> <groupId>org.junit</groupId> <artifactId>com.springsource.org.junit</artifactId> <version>4.11.0</version> </dependency> 

然后我用下面的JUnit库版本4.11replace它,一切工作正常。

 <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> </dependency> 

我有一个类似的问题,不同的原因,因此不同的解决scheme。 在我的情况下,我真的有一个单身人士的对象有一个非线程安全的方式修改成员variables的错误。 在这种情况下,遵循被接受的答案并绕过平行testing只会掩盖testing中实际显示的错误。 当然,我的解决scheme是修复devise,以便在代码中没有这种不良行为。

您不需要在JpaTransactionManager中注入数据源,因为EntityManagerFactory已经有一个数据源。 尝试以下操作:

 <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> 

通常,当testing在eclipse中传递并且使用maven失败时,这是一个类path问题,因为它是两者之间的主要区别。

所以你可以使用maven -Xtesting来检查类path,并通过菜单或项目根目录下的.classpath文件来检查eclipse的类path。

你确定例如personservice-test.xml是在类path中吗?

这帮助我解决了我的问题。 我有一个类似的症状,因为maven会失败,但运行junittesting运行良好。

事实certificate,我的父pom.xml包含以下定义:

  <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.9</version> <configuration> <forkMode>pertest</forkMode> <argLine>-Xverify:none</argLine> </configuration> </plugin> 

而在我的项目中,我重写它来删除argLine:

  <plugin> <artifactId>maven-surefire-plugin</artifactId> <configuration> <forkMode>pertest</forkMode> <argLine combine.self="override"></argLine> </configuration> </plugin> 

希望这会帮助解决surefire插件的人。

我有同样的问题,对我来说,解决scheme是让Maven处理所有的依赖,包括本地jar子。 我使用Maven进行在线依赖,并为本地依赖项手动configuration构buildpath。 因此,Maven不知道我手动configuration的依赖关系。

我使用这个解决scheme将本地jar依赖项安装到Maven中:

如何在Maven项目中添加本地jar文件?

JUnit runmaven install不同的testing执行结果似乎是几个问题的症状。

禁用线程重用testing执行也摆脱了我们的情况,但是代码不是线程安全的印象依然强大。

在我们的情况中,差异是由于存在修改testing行为的bean的存在。 只运行JUnittesting会很好,但运行项目install目标会导致testing用例失败。 由于这是一个正在开发的testing案例,因此立即产生了怀疑。

这导致另一个testing用例通过Spring实例化一个bean,直到执行新的testing用例才能存活。 bean存在正在修改一些类的行为并产生失败的结果。

在我们的解决scheme是摆脱了豆,这是不需要的第一位(又一个奖来自复制+贴枪)。

我build议大家有这个症状来调查根本原因是什么。 在testing执行中禁用线程重用可能只会隐藏它。

这很可能是你的configuration文件在src / main / resources中 ,而它们必须在src / test / resources下才能在maven下正常工作。

https://cwiki.apache.org/UIMA/differences-between-running-unit-tests-in-eclipse-and-in-maven.html

我在两年后回答这个问题,因为我在这里找不到这个答案,我认为这是正确的。