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

时间:2023-02-05 10:35:35

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:

我已经使用JUnit 4和spring测试库编写了一些JUnit测试。当我在Eclipse中运行测试时,运行良好并通过。但是,当我使用Maven(在构建过程中)运行它们时,它们不会给出spring相关的错误。我不确定是什么引起了问题,JUnit, Surefire或Spring。这是我的测试代码,spring配置和Maven的异常:

PersonServiceTest.java

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

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>

Exception in Maven

在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

16 个解决方案

#1


78  

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.xml:

我也遇到了同样的问题(JUnit测试在Maven Surefire中失败,但在Eclipse中通过),并通过将fork模式设置为始终位于Maven .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>

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

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

Edit (January 2014):

编辑(2014年1月):

As Peter Perháč pointed out, the forkMode parameter is deprecated since Surefire 2.14. Beginning from Surefire 2.14 use this instead:

正如彼得Perhač指出的那样,成功的2.14以来forkMode参数被弃用。从Surefire开始,使用以下方法:

<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

有关更多信息,请参见Fork选项和并行测试执行

#2


6  

I suddenly experienced this error, and the solution for me was to disable to run tests in parallel.

我突然遇到了这个错误,我的解决方案是禁用并行运行测试。

Your milage may vary, since I could lower number of failing tests by configuring surefire to run parallel tests by ´classes´.:

你的运费可能会有所不同,因为我可以降低数量的失败测试通过配置成功的运行并行测试´类´。:

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

As I wrote first, this was not enough for my test suite, so I completely disabled parallel by removing the <configuration> section.

正如我首先编写的,这对于我的测试套件来说是不够的,所以我删除了 节,从而完全禁用了parallel。

#3


6  

I had a similar problem, the annotation @Autowired in the test code did not work under using the Maven command line while it worked fine in Eclipse. I just update my JUnit version from 4.4 to 4.9 and the problem was solved.

我也遇到了类似的问题,测试代码中的标注@Autowired在使用Maven命令行时不工作,而在Eclipse中工作得很好。我只是将JUnit版本从4.4升级到4.9,问题就解决了。

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

#4


5  

I have the similar problem, but with IntelliJ IDEA + Maven + TestNG + spring-test. (spring-test is essential of course :) ) It was fixed when I've change config of maven-surefire-plugin to disable run tests in parallel. Like this:

我也有类似的问题,但是有IntelliJ IDEA + Maven + TestNG + spring-test。(spring-test当然是必不可少的)当我更改了maven-surefire插件的配置以禁用并行运行测试时,它被修复了。是这样的:

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

#5


3  

This doesn't exactly apply to your situation, but I had the same thing -- tests that would pass in Eclipse failed when the test goal from Maven was run.

这并不完全适用于您的情况,但是我有同样的事情——当Maven的测试目标运行时,Eclipse会通过的测试失败了。

It turned out to be a test earlier in my suite, in a different package. This took me a week to solve!

在我的套件中,在另一个包中,这是一个测试。这花了我一个星期的时间来解决!

An earlier test was testing some Logback classes, and created a Logback context from a config file.

早期的测试是测试一些Logback类,并从配置文件创建一个Logback上下文。

The later test was testing a subclass of Spring's SimpleRestTemplate, and somehow, the earlier Logback context was held, with DEBUG on. This caused extra calls to be made in RestTemplate to log HttpStatus, etc.

后来的测试是测试Spring的SimpleRestTemplate的一个子类,并且不知何故,在调试的情况下,保留了较早的Logback上下文。这导致在RestTemplate中进行额外的调用来记录HttpStatus等。

It's another thing to check if one ever gets into this situation. I fixed my problem by injecting some Mocks into my Logback test class, so that no real Logback contexts were created.

这是另一件要检查的事情如果有人进入这种情况。我通过在我的Logback测试类中注入一些mock来解决我的问题,这样就不会创建真正的Logback上下文。

#6


3  

I had the same issue, but the problem for me was that Java assertions (e.g. assert(num > 0)) were not enabled for Eclipse, but were enabled when running maven.

我也有同样的问题,但对我来说,问题是Java断言(例如assert(num > 0))在运行maven时没有启用,而是启用了。

Therefore running the jUnit tests from Eclipse did not catch trigger the assertion error.

因此,从Eclipse运行jUnit测试并没有捕获触发断言错误。

This is made clear when using jUnit 4.11 (as opposed to the older version I was using) because it prints out the assertion error, e.g.

在使用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)

#7


2  

[I am not sure that this is an answer to the original question, since the stacktrace here looks slightly different, but it may be useful to others.]

[我不确定这是否是最初问题的答案,因为stacktrace在这里看起来有点不同,但它可能对其他人有用。]

You can get tests failing in Surefire when you are also running Cobertura (to get code coverage reports). This is because Cobertura requires proxies (to measure code use) and there is some kind of conflict between those and Spring proxies. This only occurs when Spring uses cglib2, which would be the case if, for example, you have proxy-target-class="true", or if you have an object that is being proxied that does not implement interfaces.

当您同时运行Cobertura(以获得代码覆盖率报告)时,您可以在Surefire中获得测试失败。这是因为Cobertura需要代理(用来度量代码的使用),而这些代理和Spring代理之间存在某种冲突。只有在Spring使用cglib2时才会发生这种情况,例如,如果您有代理-target-class="true",或者如果您有一个正在被代理的对象没有实现接口,那么就会发生这种情况。

The normal fix to this is to add an interface. So, for example, DAOs should be interfaces, implemented by a DAOImpl class. If you autowire on the interface, everything will work fine (because cglib2 is no longer required; a simpler JDK proxy to the interface can be used instead and Cobertura works fine with this).

通常的解决方法是添加一个接口。因此,例如,DAOs应该是接口,由DAOImpl类实现。如果在接口上自动连接,一切都会正常工作(因为不再需要cglib2;可以使用更简单的接口JDK代理,Cobertura可以很好地使用它)。

However, you cannot use interfaces with annotated controllers (you will get a runtime error when trying to use the controller in a servlet) - I do not have a solution for Cobertura + Spring tests that autowire controllers.

但是,您不能使用带注释的控制器的接口(在尝试在servlet中使用控制器时将会出现运行时错误)——我没有自动连接控制器的Cobertura + Spring测试的解决方案。

#8


1  

I had this problem today testing a method that converted an object that contained a Map to a JSON string. I assume Eclipse and the Maven surefire plugin were using different JREs which had different implementations of HashMap ordering or something, which caused the tests run through Eclipse to pass and the tests run through surefire to fail (assertEquals failed). The easiest solution was to use an implementation of Map that had reliable ordering.

我今天测试了一个方法,该方法将包含映射的对象转换为JSON字符串。我假设Eclipse和Maven surefire插件使用了不同的JREs,这些JREs具有不同的HashMap排序或其他实现,这导致测试通过Eclipse运行,测试通过surefire失败(assertEquals失败)。最简单的解决方案是使用具有可靠排序的Map实现。

#9


1  

I had a similar problem: JUnit tests failed in Maven Surefire but passed in Eclipse when I used JUnit library version 4.11.0 from SpringSource Bundle Repository. Particulary:

我也遇到了类似的问题:JUnit测试在Maven Surefire中失败,但在使用SpringSource Bundle Repository版本4.11.0时在Eclipse中通过。太:

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

Then I replaced it with following JUnit library version 4.11 and everything works fine.

然后我用JUnit库版本4.11替换了它,一切都很好。

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

#10


1  

I had a similar problem with a different cause and therefore different solution. In my case, I actually had an error where a singleton object was having a member variable modified in a non-threadsafe way. In this case, following the accepted answers and circumventing the parallel testing would only hide the error that was actually revealed by the test. My solution, of course, is to fix the design so that I don't have this bad behavior in my code.

我也遇到过类似的问题,原因不同,解决方法也不同。在我的例子中,我实际上有一个错误,单例对象以非线程安全的方式修改了成员变量。在这种情况下,遵循已接受的答案并绕过并行测试只会隐藏测试实际显示的错误。当然,我的解决方案是修复设计,这样我的代码中就不会出现这种不良行为。

#11


0  

You don't need to inject a DataSource in the JpaTransactionManager since the EntityManagerFactory already has a datasource. Try the following:

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

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

#12


0  

Usually when tests pass in eclipse and fail with maven it is a classpath issue because it is the main difference between the two.

通常,当测试在eclipse中通过并在maven中失败时,这是一个类路径问题,因为这是两者之间的主要区别。

So you can check the classpath with maven -X test and check the classpath of eclipse via the menus or in the .classpath file in the root of your project.

因此,可以使用maven -X测试检查类路径,并通过菜单或项目根目录中的.classpath文件检查eclipse的类路径。

Are you sure for example that personservice-test.xml is in the classpath ?

例如,你确定那个personservice-test吗?xml在类路径中吗?

#13


0  

This has helped me in troubleshooting my problem. I had a similar symptoms in that maven would fail however running junit tests runs fine.

这帮助我解决了我的问题。我在maven中也有类似的症状,即尽管运行junit测试运行良好,maven还是会失败。

As it turns out my parent pom.xml contains the following definition:

结果是我的父母pom。xml包含以下定义:

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

And in my project I override it to remove the argLine:

在我的项目中,我重写了它以删除argLine:

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

Hopefully this will help someone in troubleshooting surefire plugin.

希望这能帮助解决问题的人,surefire插件。

#14


0  

I had the same problem, and the solution for me was to allow Maven to handle all dependencies, including to local jars. I used Maven for online dependencies, and configured build path manually for local dependencies. Thus, Maven was not aware of the dependencies I configured manually.

我有同样的问题,我的解决方案是允许Maven处理所有依赖项,包括本地jar。我使用Maven处理在线依赖项,并为本地依赖项手动配置构建路径。因此,Maven不知道我手动配置的依赖项。

I used this solution to install the local jar dependencies into Maven:

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

How to add local jar files in maven project?

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

#15


0  

Test execution result different from JUnit run and from maven install seems to be symptom for several problems.

与JUnit运行和maven安装不同的测试执行结果似乎是几个问题的症状。

Disabling thread reusing test execution did also get rid of the symptom in our case, but the impression that the code was not thread-safe was still strong.

禁用线程重用测试执行也确实消除了我们的症状,但是代码不是线程安全的印象仍然很强烈。

In our case the difference was due to the presence of a bean that modified the test behaviour. Running just the JUnit test would result fine, but running the project install target would result in a failed test case. Since it was the test case under development, it was immediately suspicious.

在我们的例子中,差异是由于存在一个修改测试行为的bean。只运行JUnit测试会得到很好的结果,但是运行项目安装目标会导致失败的测试用例。因为它是正在开发的测试用例,所以立即引起了怀疑。

It resulted that another test case was instantiating a bean through Spring that would survive until the execution of the new test case. The bean presence was modifying the behaviour of some classes and producing the failed result.

它导致另一个测试用例通过Spring实例化一个bean,该bean将一直存在,直到执行新的测试用例。bean的存在正在修改某些类的行为并产生失败的结果。

The solution in our case was getting rid of the bean, which was not needed in the first place (yet another prize from the copy+paste gun).

我们的解决方案是去掉bean,这在一开始是不需要的(又是来自copy+paste gun的奖励)。

I suggest everybody with this symptom to investigate what the root cause is. Disabling thread reuse in test execution might only hide it.

我建议每个人都有这个症状去调查什么是根本原因。在测试执行中禁用线程重用可能只会隐藏它。

#16


-1  

It is most likely that your configuration files are in src/main/resources, while they must be under src/test/resources to work properly under maven.

很可能您的配置文件在src/main/resources中,而它们必须在src/test/resources下才能在maven下正常工作。

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

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

I'm replying this after two years 'cause I couldn't find this answer here and I think it is the right one.

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

#1


78  

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.xml:

我也遇到了同样的问题(JUnit测试在Maven Surefire中失败,但在Eclipse中通过),并通过将fork模式设置为始终位于Maven .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>

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

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

Edit (January 2014):

编辑(2014年1月):

As Peter Perháč pointed out, the forkMode parameter is deprecated since Surefire 2.14. Beginning from Surefire 2.14 use this instead:

正如彼得Perhač指出的那样,成功的2.14以来forkMode参数被弃用。从Surefire开始,使用以下方法:

<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

有关更多信息,请参见Fork选项和并行测试执行

#2


6  

I suddenly experienced this error, and the solution for me was to disable to run tests in parallel.

我突然遇到了这个错误,我的解决方案是禁用并行运行测试。

Your milage may vary, since I could lower number of failing tests by configuring surefire to run parallel tests by ´classes´.:

你的运费可能会有所不同,因为我可以降低数量的失败测试通过配置成功的运行并行测试´类´。:

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

As I wrote first, this was not enough for my test suite, so I completely disabled parallel by removing the <configuration> section.

正如我首先编写的,这对于我的测试套件来说是不够的,所以我删除了 节,从而完全禁用了parallel。

#3


6  

I had a similar problem, the annotation @Autowired in the test code did not work under using the Maven command line while it worked fine in Eclipse. I just update my JUnit version from 4.4 to 4.9 and the problem was solved.

我也遇到了类似的问题,测试代码中的标注@Autowired在使用Maven命令行时不工作,而在Eclipse中工作得很好。我只是将JUnit版本从4.4升级到4.9,问题就解决了。

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

#4


5  

I have the similar problem, but with IntelliJ IDEA + Maven + TestNG + spring-test. (spring-test is essential of course :) ) It was fixed when I've change config of maven-surefire-plugin to disable run tests in parallel. Like this:

我也有类似的问题,但是有IntelliJ IDEA + Maven + TestNG + spring-test。(spring-test当然是必不可少的)当我更改了maven-surefire插件的配置以禁用并行运行测试时,它被修复了。是这样的:

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

#5


3  

This doesn't exactly apply to your situation, but I had the same thing -- tests that would pass in Eclipse failed when the test goal from Maven was run.

这并不完全适用于您的情况,但是我有同样的事情——当Maven的测试目标运行时,Eclipse会通过的测试失败了。

It turned out to be a test earlier in my suite, in a different package. This took me a week to solve!

在我的套件中,在另一个包中,这是一个测试。这花了我一个星期的时间来解决!

An earlier test was testing some Logback classes, and created a Logback context from a config file.

早期的测试是测试一些Logback类,并从配置文件创建一个Logback上下文。

The later test was testing a subclass of Spring's SimpleRestTemplate, and somehow, the earlier Logback context was held, with DEBUG on. This caused extra calls to be made in RestTemplate to log HttpStatus, etc.

后来的测试是测试Spring的SimpleRestTemplate的一个子类,并且不知何故,在调试的情况下,保留了较早的Logback上下文。这导致在RestTemplate中进行额外的调用来记录HttpStatus等。

It's another thing to check if one ever gets into this situation. I fixed my problem by injecting some Mocks into my Logback test class, so that no real Logback contexts were created.

这是另一件要检查的事情如果有人进入这种情况。我通过在我的Logback测试类中注入一些mock来解决我的问题,这样就不会创建真正的Logback上下文。

#6


3  

I had the same issue, but the problem for me was that Java assertions (e.g. assert(num > 0)) were not enabled for Eclipse, but were enabled when running maven.

我也有同样的问题,但对我来说,问题是Java断言(例如assert(num > 0))在运行maven时没有启用,而是启用了。

Therefore running the jUnit tests from Eclipse did not catch trigger the assertion error.

因此,从Eclipse运行jUnit测试并没有捕获触发断言错误。

This is made clear when using jUnit 4.11 (as opposed to the older version I was using) because it prints out the assertion error, e.g.

在使用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)

#7


2  

[I am not sure that this is an answer to the original question, since the stacktrace here looks slightly different, but it may be useful to others.]

[我不确定这是否是最初问题的答案,因为stacktrace在这里看起来有点不同,但它可能对其他人有用。]

You can get tests failing in Surefire when you are also running Cobertura (to get code coverage reports). This is because Cobertura requires proxies (to measure code use) and there is some kind of conflict between those and Spring proxies. This only occurs when Spring uses cglib2, which would be the case if, for example, you have proxy-target-class="true", or if you have an object that is being proxied that does not implement interfaces.

当您同时运行Cobertura(以获得代码覆盖率报告)时,您可以在Surefire中获得测试失败。这是因为Cobertura需要代理(用来度量代码的使用),而这些代理和Spring代理之间存在某种冲突。只有在Spring使用cglib2时才会发生这种情况,例如,如果您有代理-target-class="true",或者如果您有一个正在被代理的对象没有实现接口,那么就会发生这种情况。

The normal fix to this is to add an interface. So, for example, DAOs should be interfaces, implemented by a DAOImpl class. If you autowire on the interface, everything will work fine (because cglib2 is no longer required; a simpler JDK proxy to the interface can be used instead and Cobertura works fine with this).

通常的解决方法是添加一个接口。因此,例如,DAOs应该是接口,由DAOImpl类实现。如果在接口上自动连接,一切都会正常工作(因为不再需要cglib2;可以使用更简单的接口JDK代理,Cobertura可以很好地使用它)。

However, you cannot use interfaces with annotated controllers (you will get a runtime error when trying to use the controller in a servlet) - I do not have a solution for Cobertura + Spring tests that autowire controllers.

但是,您不能使用带注释的控制器的接口(在尝试在servlet中使用控制器时将会出现运行时错误)——我没有自动连接控制器的Cobertura + Spring测试的解决方案。

#8


1  

I had this problem today testing a method that converted an object that contained a Map to a JSON string. I assume Eclipse and the Maven surefire plugin were using different JREs which had different implementations of HashMap ordering or something, which caused the tests run through Eclipse to pass and the tests run through surefire to fail (assertEquals failed). The easiest solution was to use an implementation of Map that had reliable ordering.

我今天测试了一个方法,该方法将包含映射的对象转换为JSON字符串。我假设Eclipse和Maven surefire插件使用了不同的JREs,这些JREs具有不同的HashMap排序或其他实现,这导致测试通过Eclipse运行,测试通过surefire失败(assertEquals失败)。最简单的解决方案是使用具有可靠排序的Map实现。

#9


1  

I had a similar problem: JUnit tests failed in Maven Surefire but passed in Eclipse when I used JUnit library version 4.11.0 from SpringSource Bundle Repository. Particulary:

我也遇到了类似的问题:JUnit测试在Maven Surefire中失败,但在使用SpringSource Bundle Repository版本4.11.0时在Eclipse中通过。太:

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

Then I replaced it with following JUnit library version 4.11 and everything works fine.

然后我用JUnit库版本4.11替换了它,一切都很好。

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

#10


1  

I had a similar problem with a different cause and therefore different solution. In my case, I actually had an error where a singleton object was having a member variable modified in a non-threadsafe way. In this case, following the accepted answers and circumventing the parallel testing would only hide the error that was actually revealed by the test. My solution, of course, is to fix the design so that I don't have this bad behavior in my code.

我也遇到过类似的问题,原因不同,解决方法也不同。在我的例子中,我实际上有一个错误,单例对象以非线程安全的方式修改了成员变量。在这种情况下,遵循已接受的答案并绕过并行测试只会隐藏测试实际显示的错误。当然,我的解决方案是修复设计,这样我的代码中就不会出现这种不良行为。

#11


0  

You don't need to inject a DataSource in the JpaTransactionManager since the EntityManagerFactory already has a datasource. Try the following:

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

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

#12


0  

Usually when tests pass in eclipse and fail with maven it is a classpath issue because it is the main difference between the two.

通常,当测试在eclipse中通过并在maven中失败时,这是一个类路径问题,因为这是两者之间的主要区别。

So you can check the classpath with maven -X test and check the classpath of eclipse via the menus or in the .classpath file in the root of your project.

因此,可以使用maven -X测试检查类路径,并通过菜单或项目根目录中的.classpath文件检查eclipse的类路径。

Are you sure for example that personservice-test.xml is in the classpath ?

例如,你确定那个personservice-test吗?xml在类路径中吗?

#13


0  

This has helped me in troubleshooting my problem. I had a similar symptoms in that maven would fail however running junit tests runs fine.

这帮助我解决了我的问题。我在maven中也有类似的症状,即尽管运行junit测试运行良好,maven还是会失败。

As it turns out my parent pom.xml contains the following definition:

结果是我的父母pom。xml包含以下定义:

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

And in my project I override it to remove the argLine:

在我的项目中,我重写了它以删除argLine:

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

Hopefully this will help someone in troubleshooting surefire plugin.

希望这能帮助解决问题的人,surefire插件。

#14


0  

I had the same problem, and the solution for me was to allow Maven to handle all dependencies, including to local jars. I used Maven for online dependencies, and configured build path manually for local dependencies. Thus, Maven was not aware of the dependencies I configured manually.

我有同样的问题,我的解决方案是允许Maven处理所有依赖项,包括本地jar。我使用Maven处理在线依赖项,并为本地依赖项手动配置构建路径。因此,Maven不知道我手动配置的依赖项。

I used this solution to install the local jar dependencies into Maven:

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

How to add local jar files in maven project?

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

#15


0  

Test execution result different from JUnit run and from maven install seems to be symptom for several problems.

与JUnit运行和maven安装不同的测试执行结果似乎是几个问题的症状。

Disabling thread reusing test execution did also get rid of the symptom in our case, but the impression that the code was not thread-safe was still strong.

禁用线程重用测试执行也确实消除了我们的症状,但是代码不是线程安全的印象仍然很强烈。

In our case the difference was due to the presence of a bean that modified the test behaviour. Running just the JUnit test would result fine, but running the project install target would result in a failed test case. Since it was the test case under development, it was immediately suspicious.

在我们的例子中,差异是由于存在一个修改测试行为的bean。只运行JUnit测试会得到很好的结果,但是运行项目安装目标会导致失败的测试用例。因为它是正在开发的测试用例,所以立即引起了怀疑。

It resulted that another test case was instantiating a bean through Spring that would survive until the execution of the new test case. The bean presence was modifying the behaviour of some classes and producing the failed result.

它导致另一个测试用例通过Spring实例化一个bean,该bean将一直存在,直到执行新的测试用例。bean的存在正在修改某些类的行为并产生失败的结果。

The solution in our case was getting rid of the bean, which was not needed in the first place (yet another prize from the copy+paste gun).

我们的解决方案是去掉bean,这在一开始是不需要的(又是来自copy+paste gun的奖励)。

I suggest everybody with this symptom to investigate what the root cause is. Disabling thread reuse in test execution might only hide it.

我建议每个人都有这个症状去调查什么是根本原因。在测试执行中禁用线程重用可能只会隐藏它。

#16


-1  

It is most likely that your configuration files are in src/main/resources, while they must be under src/test/resources to work properly under maven.

很可能您的配置文件在src/main/resources中,而它们必须在src/test/resources下才能在maven下正常工作。

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

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

I'm replying this after two years 'cause I couldn't find this answer here and I think it is the right one.

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