JUnit测试在Eclipse中通过,但在Maven Surefire中失败

我已经使用JUnit 4和spring-test库编写了一些JUnit测试。当我在Eclipse中运行测试时,可以正常运行并通过。但是,当我使用Maven运行它们(在构建过程中)时,它们无法给出与Spring相关的错误。我不确定是什么引起了问题,JUnit,Surefire或Spring。这是我的测试代码,spring配置以及从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.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中的异常

-------------------------------------------------------

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

回答:

我遇到了同样的问题(JUnit测试在Maven Surefire中失败,但在Eclipse中通过了),并设法通过将forkMode 始终设置为pom.xml中的maven surefire配置来解决了这个问题:

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-surefire-plugin</artifactId>

<version>2.12</version>

<configuration>

<forkMode>always</forkMode>

</configuration>

</plugin>

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

以上是 JUnit测试在Eclipse中通过,但在Maven Surefire中失败 的全部内容, 来源链接: utcz.com/qa/405702.html

回到顶部