简体   繁体   English

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

[英]JUnit tests pass in Eclipse but fail in Maven Surefire

I have written some JUnit tests using JUnit 4 and spring-test libraries.我已经使用 JUnit 4 和 spring-test 库编写了一些 JUnit 测试。 When I run the tests inside Eclipse then run fine and pass.当我在 Eclipse 中运行测试时,运行良好并通过。 But when I run them using Maven (during the build process), they fail giving a spring related error.但是当我使用 Maven 运行它们时(在构建过程中),它们无法给出与弹簧相关的错误。 I am not sure what is causing the problem, JUnit, Surefire or Spring.我不确定是什么导致了这个问题,JUnit、Surefire 还是 Spring。 Here is my test code, spring configuration and the exception that I get from Maven:这是我的测试代码、spring 配置和我从 Maven 得到的异常:

PersonServiceTest.java人员服务测试.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人员服务-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

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 中通过)并设法通过在 pom.xml 中的 maven surefire配置中将forkMode设置为always来解决它:

<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 Surefire 参数: 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.正如Peter Perháč指出的那样,自 Surefire 2.14 起不推荐使用 forkMode 参数。 Beginning from Surefire 2.14 use this instead:从 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>

For more information see Fork Options and Parallel Test Execution有关更多信息,请参阅Fork 选项和并行测试执行

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´.:您的里程可能会有所不同,因为我可以通过将 surefire 配置为按“类”运行并行测试来减少失败测试的数量。:

            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.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.正如我第一次写的那样,这对于我的测试套件来说还不够,所以我通过删除<configuration>部分完全禁用了并行。

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.我有一个类似的问题,测试代码中的注释@Autowired在使用 Maven 命令行时不起作用,而它在 Eclipse 中运行良好。 I just update my JUnit version from 4.4 to 4.9 and the problem was solved.我只是将我的 JUnit 版本从 4.4 更新到 4.9,问题就解决了。

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

Test execution result different from JUnit run and from maven install seems to be symptom for several problems.JUnit runmaven install不同的测试执行结果似乎是几个问题的症状。

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.在我们的例子中,差异是由于存在修改测试行为的 bean。 Running just the JUnit test would result fine, but running the project install target would result in a failed test case.只运行 JUnit 测试会很好,但运行项目install目标会导致测试用例失败。 Since it was the test case under development, it was immediately suspicious.既然是正在开发的测试用例,立马就起了疑心。

It resulted that another test case was instantiating a bean through Spring that would survive until the execution of the new test case.这导致另一个测试用例通过 Spring 实例化一个 bean,该 bean 将一直存在,直到执行新的测试用例。 The bean presence was modifying the behaviour of some classes and producing the failed result. 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,这首先是不需要的(复制+粘贴枪的另一个奖品)。

I suggest everybody with this symptom to investigate what the root cause is.我建议每个有这种症状的人调查根本原因是什么。 Disabling thread reuse in test execution might only hide it.在测试执行中禁用线程重用可能只会隐藏它。

I have the similar problem, but with IntelliJ IDEA + Maven + TestNG + spring-test.我有类似的问题,但使用 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. spring-test当然是必不可少的 :) )当我更改maven-surefire-plugin 的配置以禁用并行运行测试时,它已修复。 Like this:像这样:

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

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.后来的测试是测试 Spring 的 SimpleRestTemplate 的一个子类,不知何故,保留了较早的 Logback 上下文,并打开了 DEBUG。 This caused extra calls to be made in RestTemplate to log HttpStatus, etc.这导致在 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.我通过将一些 Mock 注入我的 Logback 测试类来解决我的问题,因此没有创建真正的 Logback 上下文。

I had the same issue, but the problem for me was that Java assertions (eg assert(num > 0)) were not enabled for Eclipse, but were enabled when running maven.我有同样的问题,但对我来说问题是 Java 断言(例如 assert(num > 0))没有为 Eclipse 启用,但是在运行 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, eg使用 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)

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.当然,我的解决方案是修复设计,这样我的代码中就不会出现这种不良行为。

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.我有一个类似的问题:JUnit 测试在 Maven Surefire 中失败,但当我使用 SpringSource Bundle Repository 中的 JUnit 库版本 4.11.0 时,JUnit 测试在 Eclipse 中通过。 Particulary:特别是:

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

[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.] [我不确定这是对原始问题的回答,因为这里的堆栈跟踪看起来略有不同,但对其他人可能有用。]

You can get tests failing in Surefire when you are also running Cobertura (to get code coverage reports).当您还运行 Cobertura(以获取代码覆盖率报告)时,您可能会在 Surefire 中测试失败。 This is because Cobertura requires proxies (to measure code use) and there is some kind of conflict between those and Spring proxies.这是因为 Cobertura 需要代理(以衡量代码使用情况),并且这些代理与 Spring 代理之间存在某种冲突。 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.在 Spring 使用 cglib2 时发生,例如,如果您有proxy-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.因此,例如,DAO 应该是接口,由 DAOImpl 类实现。 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).如果您在接口上自动装配,一切都会正常工作(因为不再需要 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 测试的解决方案。

In my case the reason was a bug in the code.就我而言,原因是代码中的错误。 The test relied on a certain order of elements in a HashSet , which turned out to be different when run either in Eclipse or in Maven Surefire.测试依赖于HashSet中元素的特定顺序,结果证明在 Eclipse 或 Maven Surefire 中运行时会有所不同。

I had a similar problem, I ran my tests disabling the reuse of forks like this我有一个类似的问题,我运行了我的测试,禁用了这样的叉子的重用

mvn clean test -DreuseForks=false

and the problem disappeared.问题就消失了。 The downside is that the overall test execution time will be longer, that's why you may want to do this from the command line only if necessary缺点是整体测试执行时间会更长,这就是为什么您可能只想在必要时从命令行执行此操作

I had this problem today testing a method that converted an object that contained a Map to a JSON string.我今天遇到了这个问题,测试了一种将包含Map的对象转换为 JSON 字符串的方法。 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).我假设 Eclipse 和 Maven surefire 插件使用不同的 JRE,它们具有不同的HashMap排序实现或其他东西,这导致通过 Eclipse 运行的测试通过,而通过 surefire 运行的测试失败( assertEquals失败)。 The easiest solution was to use an implementation of Map that had reliable ordering.最简单的解决方案是使用具有可靠排序的 Map 实现。

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 测试运行良好。

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 插件进行故障排除。

I had the same problem, and the solution for me was to allow Maven to handle all dependencies, including to local jars.我遇到了同样的问题,我的解决方案是允许 Maven 处理所有依赖项,包括本地 jars。 I used Maven for online dependencies, and configured build path manually for local dependencies.在线依赖使用Maven,本地依赖手动配置构建路径。 Thus, Maven was not aware of the dependencies I configured manually.因此,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文件?

You don't need to inject a DataSource in the JpaTransactionManager since the EntityManagerFactory already has a datasource.您不需要在 JpaTransactionManager 中注入数据源,因为 EntityManagerFactory 已经有一个数据源。 Try the following:请尝试以下操作:

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

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 test 检查类路径,并通过菜单或项目根目录中的 .classpath 文件检查 eclipse 的类路径。

Are you sure for example that personservice-test.xml is in the classpath ?例如,您确定 personservice-test.xml 在类路径中吗?

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.我在两年后回答这个问题,因为我在这里找不到这个答案,我认为这是正确的答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM