JUnit-Tests bestehen in Eclipse, in Maven Surefire jedoch nicht


95

Ich habe einige JUnit-Tests mit JUnit 4 und Spring-Test-Bibliotheken geschrieben. Wenn ich die Tests in Eclipse ausführe, laufen sie gut und bestehen. Wenn ich sie jedoch mit Maven ausführe (während des Erstellungsprozesses), geben sie keinen federbezogenen Fehler aus. Ich bin nicht sicher, was das Problem verursacht, JUnit, Surefire oder Spring. Hier ist mein Testcode, die Federkonfiguration und die Ausnahme, die ich von Maven bekomme:

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());
            }});
    }

}

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

Ausnahme in Maven

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.xyz.person.test.PersonServiceTest
23:18:51,250  WARN JDBCExceptionReporter:77 - SQL Warning: 10000, SQLState: 01J01
23:18:51,281  WARN JDBCExceptionReporter:78 - Database 'InMemoryDatabase' not created, connection made to existing database instead.
23:18:52,937  WARN JDBCExceptionReporter:77 - SQL Warning: 10000, SQLState: 01J01
23:18:52,937  WARN JDBCExceptionReporter:78 - Database 'InMemoryDatabase' not created, connection made to existing database instead.
23:18:52,953  WARN TestContextManager:429 - Caught exception while allowing TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener@359a359a] to process 'after' execution for test: method [public void com.xyz.person.test.PersonServiceTest.testCreatePerson()], instance [com.xyz.person.test.PersonServiceTest@1bc81bc8], exception [org.springframework.transaction.IllegalTransactionStateException: Pre-bound JDBC Connection found! JpaTransactionManager does not support running within DataSourceTransactionManager if told to manage the DataSource itself. It is recommended to use a single JpaTransactionManager for all transactions on a single DataSource, no matter whether JPA or JDBC access.]
java.lang.IllegalStateException: No value for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@3f563f56] bound to thread [main]
        at org.springframework.transaction.support.TransactionSynchronizationManager.unbindResource(TransactionSynchronizationManager.java:199)
        at org.springframework.orm.jpa.JpaTransactionManager.doCleanupAfterCompletion(JpaTransactionManager.java:489)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.cleanupAfterCompletion(AbstractPlatformTransactionManager.java:1011)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:804)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
        at org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.endTransaction(TransactionalTestExecutionListener.java:515)
        at org.springframework.test.context.transaction.TransactionalTestExecutionListener.endTransaction(TransactionalTestExecutionListener.java:290)
        at org.springframework.test.context.transaction.TransactionalTestExecutionListener.afterTestMethod(TransactionalTestExecutionListener.java:183)
        at org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:426)
        at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:90)
        at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
        at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
        at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
        at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:59)
        at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:115)
        at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:102)
        at org.apache.maven.surefire.Surefire.run(Surefire.java:180)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
        at java.lang.reflect.Method.invoke(Method.java:599)
        at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:350)
        at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021)
23:18:53,078  WARN TestContextManager:377 - Caught exception while allowing TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener@359a359a] to process 'before' execution of test method [public void com.xyz.person.test.PersonServiceTest.testFindPersons()] for test instance [com.xyz.person.test.PersonServiceTest@79f279f2]
org.springframework.transaction.IllegalTransactionStateException: Pre-bound JDBC Connection found! JpaTransactionManager does not support running within DataSourceTransactionManager if told to manage the DataSource itself. It is recommended to use a single JpaTransactionManager for all transactions on a single DataSource, no matter whether JPA or JDBC access.
        at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:304)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371)
        at org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.startTransaction(TransactionalTestExecutionListener.java:507)
        at org.springframework.test.context.transaction.TransactionalTestExecutionListener.startNewTransaction(TransactionalTestExecutionListener.java:269)
        at org.springframework.test.context.transaction.TransactionalTestExecutionListener.beforeTestMethod(TransactionalTestExecutionListener.java:162)
        at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:374)
        at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:73)
        at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
        at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
        at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
        at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
        at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:59)
        at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:115)
        at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:102)
        at org.apache.maven.surefire.Surefire.run(Surefire.java:180)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
        at java.lang.reflect.Method.invoke(Method.java:599)
        at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:350)
        at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021)
Tests run: 3, Failures: 0, Errors: 3, Skipped: 0, Time elapsed: 15.625 sec <<< FAILURE!

Results :

Tests in error:
  testCreatePerson(com.xyz.person.test.PersonServiceTest)
  testCreatePerson(com.xyz.person.test.PersonServiceTest)
  testFindPersons(com.xyz.person.test.PersonServiceTest)

Tests run: 3, Failures: 0, Errors: 3, Skipped: 0

Haben Sie eine spezielle Konfiguration des todsicheren Plugins in Ihrem POM?
Matt B

@ Matt Ich habe keine Konfiguration für todsichere in meinem Pom
Abhinav Sarkar

1
Ich bin zu diesem Artikel gekommen, weil ich das gleiche Problem hatte, aber in meinem Fall habe ich eine andere Lösung verwendet. Nachdem ich DEBUG-Protokolle für meine Tests aktiviert hatte, stellte ich fest, dass Spring Framework einen alten MongoDB-Datenbanknamen ansah. Dieser Name wurde in einer alten Version eines JARs festgelegt, das von einem anderen Projekt in meinem Arbeitsbereich erstellt wurde (obwohl es mehrmals mit erstellt wurde der neue Name). Einige Maven Clen +, die die Bibliotheken auf meiner .m2 löschten, gefolgt von Maven Install all dieser Projekte, lösten das Problem. Obwohl es keinen Grund für das Projekt gab, sich ein altes Glas anzusehen (es wurde leider irgendwo zwischengespeichert)
Cotta

Antworten:


107

Ich hatte das gleiche Problem (JUnit-Tests in Maven Surefire fehlgeschlagen, aber in Eclipse bestanden) und konnte es lösen, indem ich forkMode in pom.xml auf immer in der Maven-Surefire- Konfiguration setzte:

<plugin>
    <groupId> org.apache.maven.plugins </ groupId>
    <artifactId> Maven-Surefire-Plugin </ Artefakt-ID>
    <Version> 2.12 </ Version>
    <Konfiguration>
        <forkMode> immer </ forkMode>
    </ configuration>
</ plugin>

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

Bearbeiten (Januar 2014):

Wie Peter Perháč betonte, ist der Parameter forkMode seit Surefire 2.14 veraltet. Verwenden Sie ab Surefire 2.14 stattdessen Folgendes:

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

Weitere Informationen finden Sie unter Gabeloptionen und parallele Testausführung


Danke! Das Problem wurde für mich behoben. Irgendeine Idee warum?
Alex

6
Gut zu hören. In meinem Fall war das Problem sehr wahrscheinlich, dass eine vom JUnit-Test gelesene Konfigurationsdatei im Speicher blieb und das Ergebnis eines nachfolgenden Tests beschädigte. Wenn forkMode auf true gesetzt ist, wird jede Testklasse völlig unabhängig von der anderen ausgeführt, um sicherzustellen, dass die Tests ohne Nebenwirkungen ausgeführt werden.
Simon

4
Ich habe dies gerade mit surefire 2.16 versucht und festgestellt: "Der Parameter forkMode ist seit Version 2.14 veraltet. Verwenden Sie stattdessen forkCount und reuseForks."
Also

1
Sie können höchstwahrscheinlich eine höhere Anzahl von Gabeln verwenden. Wichtig ist hierbei, dass Gabeln nicht wiederverwendet werden und eine einzelne Gabel dazu führt, dass die Erstellung von Paketen sehr lange dauert.
Sandy Simonton

1
Plus eins für die Aktualisierung Ihrer Antwort zwei Jahre später
Gerben Rampaart

7

Dieser Fehler trat plötzlich auf, und die Lösung für mich bestand darin, die parallele Ausführung von Tests zu deaktivieren.

Ihr Kilometerstand kann variieren, da ich die Anzahl der fehlgeschlagenen Tests verringern könnte, indem ich todsicher konfiguriere, um parallele Tests nach Klassen durchzuführen:

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

Wie ich zuerst schrieb, war dies für meine Testsuite nicht ausreichend, daher habe ich parallel durch Entfernen des <configuration>Abschnitts vollständig deaktiviert .


7

Ich hatte ein ähnliches Problem. Die Anmerkung @Autowiredim Testcode funktionierte nicht unter Verwendung der Maven-Befehlszeile, während sie in Eclipse einwandfrei funktionierte. Ich habe gerade meine JUnit-Version von 4.4 auf 4.9 aktualisiert und das Problem wurde behoben.

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

5

Dies trifft nicht genau auf Ihre Situation zu, aber ich hatte das Gleiche - Tests, die in Eclipse bestanden wurden, schlugen fehl, als das Testziel von Maven ausgeführt wurde.

Es stellte sich heraus, dass es sich früher in meiner Suite um einen Test in einem anderen Paket handelte . Ich habe eine Woche gebraucht, um es zu lösen!

Ein früherer Test testete einige Logback-Klassen und erstellte einen Logback-Kontext aus einer Konfigurationsdatei.

Der spätere Test testete eine Unterklasse von Spring's SimpleRestTemplate, und irgendwie wurde der frühere Logback-Kontext mit aktiviertem DEBUG gehalten. Dies führte dazu, dass in RestTemplate zusätzliche Aufrufe zum Protokollieren von HttpStatus usw. getätigt wurden.

Es ist eine andere Sache zu überprüfen, ob man jemals in diese Situation gerät. Ich habe mein Problem behoben, indem ich einige Mocks in meine Logback-Testklasse eingefügt habe, sodass keine echten Logback-Kontexte erstellt wurden.


Danke für den Zeiger. Ich stieß auf ein ähnliches Problem, bei dem im Standard-Maven-Projekt ein traditioneller Testfall automatisch generiert wurde (den ich ignorierte), während ich SpringJUnit4ClassRunner für meine neuen Testfälle verwendete. Das Hinzufügen der SpringJUnit4ClassRunner-Annotation zum automatisch generierten Test hat das Problem für mich gelöst.
Avnish

5

Ich habe das ähnliche Problem, aber mit IntelliJ IDEA + Maven + TestNG + Federtest. ( Frühlingstest ist natürlich wichtig :)) Es wurde behoben, als ich die Konfiguration des Maven-Surefire-Plugins geändert habe , um parallel laufende Tests zu deaktivieren. So was:

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

4

Das von JUnit runund von abweichende Ergebnis der Testausführung maven installscheint ein Symptom für verschiedene Probleme zu sein.

Das Deaktivieren der Testausführung zur Wiederverwendung von Threads hat in unserem Fall auch das Symptom beseitigt, aber der Eindruck, dass der Code nicht threadsicher war, war immer noch stark.

In unserem Fall war der Unterschied auf das Vorhandensein einer Bohne zurückzuführen, die das Testverhalten veränderte. Das Ausführen nur des JUnit-Tests würde in Ordnung sein, das Ausführen des Projektziels installwürde jedoch zu einem fehlgeschlagenen Testfall führen. Da es sich um den in der Entwicklung befindlichen Testfall handelte, war er sofort verdächtig.

Es ergab sich, dass ein anderer Testfall eine Bohne durch Spring instanziierte, die bis zur Ausführung des neuen Testfalls überleben würde. Die Bean-Präsenz veränderte das Verhalten einiger Klassen und führte zu dem fehlgeschlagenen Ergebnis.

Die Lösung in unserem Fall bestand darin, die Bohne loszuwerden, die überhaupt nicht benötigt wurde (ein weiterer Preis von der Copy + Paste- Pistole).

Ich schlage jedem mit diesem Symptom vor, die Grundursache zu untersuchen. Durch Deaktivieren der Thread-Wiederverwendung bei der Testausführung wird diese möglicherweise nur ausgeblendet.


3

Ich hatte das gleiche Problem, aber das Problem für mich war, dass Java-Zusicherungen (z. B. assert (num> 0)) nicht für Eclipse aktiviert waren, sondern beim Ausführen von maven.

Daher hat das Ausführen der jUnit-Tests von Eclipse den Assertionsfehler nicht ausgelöst.

Dies wird bei Verwendung von jUnit 4.11 (im Gegensatz zu der älteren Version, die ich verwendet habe) deutlich, da der Assertionsfehler ausgedruckt wird, z

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)

In diesem Fall ist dieser Link relevant: Confluence.atlassian.com/display/JIRAKB/…
OhadR

... und im Falle von Gradle fügen Sie Folgendes hinzu: test {enableAssertions = false ignoreFailures = true}
OhadR

3

Ich hatte ein ähnliches Problem mit einer anderen Ursache und daher einer anderen Lösung. In meinem Fall hatte ich tatsächlich einen Fehler, bei dem ein Singleton-Objekt eine Mitgliedsvariable hatte, die nicht threadsicher geändert wurde. In diesem Fall würde das Befolgen der akzeptierten Antworten und das Umgehen des parallelen Tests nur den Fehler verbergen, der durch den Test tatsächlich aufgedeckt wurde. Meine Lösung besteht natürlich darin, das Design so zu korrigieren, dass ich dieses schlechte Verhalten nicht in meinem Code habe.


2

[Ich bin nicht sicher, ob dies eine Antwort auf die ursprüngliche Frage ist, da der Stacktrace hier etwas anders aussieht, aber für andere nützlich sein kann.]

In Surefire können Tests fehlschlagen, wenn Sie auch Cobertura ausführen (um Berichte zur Codeabdeckung zu erhalten). Dies liegt daran, dass Cobertura Proxys benötigt (um die Verwendung von Code zu messen) und es einen Konflikt zwischen diesen und Spring-Proxys gibt. Dies tritt nur auf, wenn Spring cglib2 verwendet. Dies ist beispielsweise der Fall, proxy-target-class="true"wenn Sie über ein Proxy-Objekt verfügen, das keine Schnittstellen implementiert.

Die normale Lösung besteht darin, eine Schnittstelle hinzuzufügen. So sollten DAOs beispielsweise Schnittstellen sein, die von einer DAOImpl-Klasse implementiert werden. Wenn Sie die Schnittstelle automatisch verdrahten, funktioniert alles einwandfrei (da cglib2 nicht mehr benötigt wird; stattdessen kann ein einfacherer JDK-Proxy für die Schnittstelle verwendet werden, und Cobertura funktioniert damit einwandfrei).

Sie können jedoch keine Schnittstellen mit mit Anmerkungen versehenen Controllern verwenden (beim Versuch, den Controller in einem Servlet zu verwenden, wird ein Laufzeitfehler angezeigt). Ich habe keine Lösung für Cobertura + Spring-Tests, bei denen Controller automatisch verdrahtet werden.


2

Ich hatte ein ähnliches Problem: JUnit-Tests sind in Maven Surefire fehlgeschlagen, wurden jedoch in Eclipse bestanden, als ich die JUnit-Bibliotheksversion 4.11.0 aus dem SpringSource Bundle Repository verwendete. Insbesondere:

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

Dann habe ich es durch die folgende JUnit-Bibliothek Version 4.11 ersetzt und alles funktioniert gut.

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

Das hat den Trick für mich getan. Meine Tests wurden sofort ausgeführt, als ich Maven über die Befehlszeile ausführte. In Eclipse musste ich das Projekt jedoch schließen und erneut öffnen, bevor die Komponententests im JUnit-Fenster ausgeführt wurden.
Marvo

1

Ich hatte heute dieses Problem beim Testen einer Methode, die ein Objekt, das a enthielt, Mapin eine JSON-Zeichenfolge konvertierte . Ich gehe davon aus, dass Eclipse und das Maven-Safefire-Plugin unterschiedliche JREs mit unterschiedlichen HashMapOrdnungsimplementierungen oder Ähnlichem verwendeten, was dazu führte, dass die durch Eclipse durchgeführten Tests bestanden wurden und die durch Surefire durchgeführten Tests fehlschlugen ( assertEqualsfehlgeschlagen). Die einfachste Lösung war die Verwendung einer Map-Implementierung mit zuverlässiger Bestellung.


0

Sie müssen keine DataSource in den JpaTransactionManager einfügen, da die EntityManagerFactory bereits über eine Datenquelle verfügt. Versuche Folgendes:

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

Die Tests schlagen (mit Fehlern) in Eclipse fehl, wenn ich die Datenquelle aus der TransactionManager-Bean entferne.
Abhinav Sarkar

0

Wenn Tests in Eclipse bestanden werden und mit Maven fehlschlagen, handelt es sich normalerweise um ein Klassenpfadproblem, da dies der Hauptunterschied zwischen beiden ist.

Sie können also den Klassenpfad mit maven -X test überprüfen und den Klassenpfad von Eclipse über die Menüs oder in der .classpath-Datei im Stammverzeichnis Ihres Projekts überprüfen.

Sind Sie sich zum Beispiel sicher, dass sich die Personenservice-test.xml im Klassenpfad befindet?


Ja, da ich die INFO-Protokolle aus dem Spring-Kontext sehen kann, die während des Maven-Testlaufs in die Konsole geladen werden.
Abhinav Sarkar

0

Dies hat mir bei der Fehlerbehebung geholfen. Ich hatte ähnliche Symptome, dass Maven fehlschlagen würde, aber das Ausführen von Junit-Tests läuft einwandfrei.

Wie sich herausstellt, enthält meine übergeordnete pom.xml die folgende Definition:

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

Und in meinem Projekt überschreibe ich es, um die argLine zu entfernen:

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

Hoffentlich hilft dies jemandem bei der Fehlerbehebung bei todsicheren Plugins.



0

Ich hatte das gleiche Problem und die Lösung für mich bestand darin, Maven zu erlauben, alle Abhängigkeiten zu handhaben, einschließlich lokaler Gläser. Ich habe Maven für Online-Abhängigkeiten verwendet und den Erstellungspfad manuell für lokale Abhängigkeiten konfiguriert. Daher war Maven die von mir manuell konfigurierten Abhängigkeiten nicht bekannt.

Ich habe diese Lösung verwendet, um die lokalen JAR-Abhängigkeiten in Maven zu installieren:

Wie füge ich lokale JAR-Dateien in ein Maven-Projekt ein?


0

In meinem Fall war der Grund ein Fehler im Code. Der Test stützte sich auf eine bestimmte Reihenfolge von Elementen in a HashSet, die sich als unterschiedlich herausstellte, wenn sie entweder in Eclipse oder in Maven Surefire ausgeführt wurden.


-2

Es ist sehr wahrscheinlich, dass sich Ihre Konfigurationsdateien in src / main / resources befinden , während sie sich unter src / test / resources befinden müssen, damit sie unter maven ordnungsgemäß funktionieren.

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

Ich antworte darauf nach zwei Jahren, weil ich diese Antwort hier nicht finden konnte und ich denke, dass es die richtige ist.


Nein, es ist umgekehrt. src/main/resourcesist für Tests src/test/resourcessichtbar, für Produktionscode jedoch nicht.
Christoffer Hammarström

Der Link, den Sie hinzugefügt haben, handelt von Abhängigkeiten zwischen Projekten, nicht innerhalb von main / test im selben Projekt
eis
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.