Testy JUnit przechodzą w Eclipse, ale kończą się niepowodzeniem w Maven Surefire

99

Napisałem kilka testów JUnit przy użyciu JUnit 4 i bibliotek testów sprężynowych. Kiedy uruchamiam testy w Eclipse, działają dobrze i zdają. Ale kiedy uruchamiam je za pomocą Mavena (podczas procesu kompilacji), zawodzą, dając błąd związany ze sprężyną. Nie jestem pewien, co powoduje problem, JUnit, Surefire czy Spring. Oto mój kod testowy, konfiguracja sprężyn i wyjątek, który otrzymałem od Mavena:

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

}

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

Wyjątek w 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
Abhinav Sarkar
źródło
czy masz jakąś specjalną konfigurację pewnej wtyczki w swoim POM?
mat b
@matt Nie mam żadnej konfiguracji na pewno w moim pom
Abhinav Sarkar
1
Przyszedłem do tego artykułu, ponieważ miałem ten sam problem, ale w moim przypadku zastosowałem inne rozwiązanie. Po włączeniu dzienników DEBUG na moich testach dowiedziałem się, że Spring Framework szukał starej nazwy bazy danych MongoDB, a ta nazwa została ustawiona w starej wersji jar utworzonej przez inny projekt na moim obszarze roboczym (chociaż był on budowany kilka razy z nowa nazwa). Niektóre Maven Clen + usuwanie bibliotek na moim .m2, a następnie Maven Install wszystkich tych projektów rozwiązało problem. Chociaż nie było powodu, aby projekt patrzył na stary słoik (niestety był gdzieś w pamięci podręcznej)
Cotta

Odpowiedzi:

109

Miałem ten sam problem (testy JUnit nie powiodły się w Maven Surefire, ale przeszły w Eclipse) i udało mi się go rozwiązać, ustawiając forkMode na zawsze w konfiguracji Maven surefire w pom.xml:

<plugin>
    <groupId> org.apache.maven.plugins </groupId>
    <artifactId> maven-surefire-plugin </artifactId>
    <version> 2.12 </version>
    <konfiguracja>
        <forkMode> zawsze </forkMode>
    </configuration>
</plugin>

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

Edycja (styczeń 2014):

Jak zauważył Peter Perháč , parametr forkMode jest przestarzały od wersji Surefire 2.14. Począwszy od Surefire 2.14 użyj zamiast tego:

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

Aby uzyskać więcej informacji, zobacz Opcje rozwidlenia i równoległe wykonywanie testów

Szymon
źródło
6
Dobrze to słyszeć. W moim przypadku problem był bardzo prawdopodobny, że plik konfiguracyjny odczytany przez test JUnit pozostał w pamięci, uszkadzając wynik kolejnego testu. Gdy forkMode ma wartość true, każda klasa testowa jest wykonywana całkowicie niezależnie od drugiej, co gwarantuje, że testy są wykonywane bez skutków ubocznych.
simon
4
właśnie wypróbowałem to przy użyciu surefire 2.16 i otrzymałem: "Parametr forkMode jest przestarzały od wersji 2.14. Zamiast tego użyj forkCount i reuseForks." więc uważaj, to działa tylko przed 2.14
Peter Perháč
1
Najprawdopodobniej możesz użyć większej liczby rozwidleń, ważne jest tutaj to, że widelce nie są ponownie używane, a pojedynczy rozwidlenie spowoduje, że kompilacja pakietów zajmie bardzo dużo czasu.
Sandy Simonton
1
Plus jeden za zaktualizowanie odpowiedzi dwa lata później
Gerben Rampaart
1
@SteveChambers Trochę się spóźniłem, ale myślę, że 1 na rdzeń procesora jest rozsądny (forkCount = 1C) - oczywiście zależy to od maszyny budującej.
Sandy Simonton
7

Nagle doświadczyłem tego błędu i rozwiązaniem dla mnie było wyłączenie równoległego uruchamiania testów.

Twój przebieg może się różnić, ponieważ mogłem zmniejszyć liczbę testów zakończonych niepowodzeniem, konfigurując surefire do uruchamiania testów równoległych według „klas”:

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

Jak napisałem najpierw, to nie wystarczyło dla mojego zestawu testów, więc całkowicie wyłączyłem równolegle, usuwając <configuration>sekcję.

Jesper Rønn-Jensen
źródło
7

Miałem podobny problem, adnotacja @Autowiredw kodzie testowym nie działała przy użyciu wiersza poleceń Maven, podczas gdy działała dobrze w Eclipse. Właśnie zaktualizowałem wersję JUnita z 4.4 do 4.9 i problem został rozwiązany.

<dependency>
    <groupId>junit</groupId
    <artifactId>junit</artifactId>
    <version>4.9</version>
</dependency>
cartman1989
źródło
5

Nie dotyczy to dokładnie twojej sytuacji, ale miałem to samo - testy, które przeszłyby w Eclipse, zawiodły, gdy został uruchomiony cel testowy z Mavena.

Okazało się, że był to test wcześniej w moim pakiecie, w innym pakiecie . Rozwiązanie tego zajęło mi tydzień!

Wcześniejszy test testował niektóre klasy Logback i tworzył kontekst Logback z pliku konfiguracyjnego.

W późniejszym teście testowano podklasę SimpleRestTemplate Springa iw jakiś sposób wcześniejszy kontekst Logback został zachowany, z włączonym DEBUG. Spowodowało to dodatkowe wywołania w RestTemplate do rejestrowania HttpStatus itp.

Kolejną rzeczą jest sprawdzenie, czy ktoś kiedykolwiek znajdzie się w takiej sytuacji. Naprawiłem mój problem, wstrzykując niektóre Mocks do mojej klasy testowej Logback, tak że nie zostały utworzone żadne rzeczywiste konteksty Logback.

Jim Jarrett
źródło
Dzięki za wskazówkę. Napotkałem podobny problem, w którym domyślny projekt maven miał automatycznie generowany tradycyjny przypadek testowy (który zignorowałem), podczas gdy używałem SpringJUnit4ClassRunner do moich nowych przypadków testowych. Dodanie adnotacji SpringJUnit4ClassRunner do autogenerowanego testu rozwiązało problem.
Avnish
5

Mam podobny problem, ale z IntelliJ IDEA + Maven + TestNG + test sprężynowy. ( test sprężynowy jest oczywiście niezbędny :)) Zostało to naprawione, gdy zmieniłem konfigurację wtyczki maven-surefire, aby wyłączyć równoległe uruchamianie testów. Lubię to:

<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>
s13o
źródło
4

Wynik wykonania testu różni się od JUnit runi od maven installwydaje się objawiać kilka problemów.

Wyłączenie wykonywania testów ponownego wykorzystania wątków również pozwoliło pozbyć się symptomu w naszym przypadku, ale wrażenie, że kod nie jest bezpieczny dla wątków, było nadal silne.

W naszym przypadku różnica wynikała z obecności fasoli, która modyfikowała zachowanie testu. Uruchomienie samego testu JUnit installzakończyłoby się pomyślnie , ale uruchomienie celu projektu spowodowałoby niepowodzenie przypadku testowego. Ponieważ był to przypadek testowy w fazie rozwoju, od razu stał się podejrzany.

Spowodowało to, że inny przypadek testowy tworzył komponent bean za pośrednictwem Springa, który miał przetrwać do wykonania nowego przypadku testowego. Obecność fasoli modyfikowała zachowanie niektórych klas i dawała nieudany wynik.

Rozwiązaniem w naszym przypadku było pozbycie się fasoli, która w pierwszej kolejności nie była potrzebna (kolejna nagroda z pistoletu kopiuj + wklej ).

Sugeruję każdemu, kto ma ten objaw, aby zbadał podstawową przyczynę. Wyłączenie ponownego użycia wątku podczas wykonywania testu może to tylko ukryć.

manuelvigarcia
źródło
3

Miałem ten sam problem, ale problem polegał na tym, że asercje Java (np. Assert (num> 0)) nie były włączone dla Eclipse, ale były włączone podczas uruchamiania maven.

Dlatego uruchomienie testów jUnit z Eclipse nie wywołało błędu asercji.

Jest to jasne, gdy używam jUnit 4.11 (w przeciwieństwie do starszej wersji, z której korzystałem), ponieważ wyświetla błąd asercji, np.

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)
Ryan
źródło
w tym przypadku ten link jest istotny: confluence.atlassian.com/display/JIRAKB/ ...
OhadR
... aw przypadku gradle dodaj to: test {enableAssertions = false ignoreFailures = true}
OhadR
3

Miałem podobny problem z inną przyczyną i dlatego innym rozwiązaniem. W moim przypadku faktycznie wystąpił błąd polegający na tym, że pojedynczy obiekt miał zmienną składową zmodyfikowaną w sposób bez ochrony wątków. W takim przypadku podążanie za zaakceptowanymi odpowiedziami i omijanie równoległego testowania tylko ukrywałoby błąd, który został faktycznie ujawniony przez test. Moim rozwiązaniem jest oczywiście naprawienie projektu tak, aby nie było tego złego zachowania w moim kodzie.

Cegła
źródło
2

[Nie jestem pewien, czy jest to odpowiedź na pierwotne pytanie, ponieważ ślad stosu wygląda tutaj nieco inaczej, ale może być przydatny dla innych.]

Możesz otrzymać testy zakończone niepowodzeniem w Surefire, gdy używasz również Cobertury (aby uzyskać raporty pokrycia kodu). Dzieje się tak, ponieważ Cobertura wymaga serwerów proxy (do pomiaru wykorzystania kodu) i istnieje pewien konflikt między nimi a serwerami proxy Spring. Dzieje się tak tylko wtedy, gdy Spring używa cglib2, co miałoby miejsce, gdyby na przykład tak byłoproxy-target-class="true" lub masz obiekt, który jest proxy, który nie implementuje interfejsów.

Normalnym rozwiązaniem jest dodanie interfejsu. Na przykład DAO powinny być interfejsami implementowanymi przez klasę DAOImpl. Jeśli automatycznie połączysz się z interfejsem, wszystko będzie działać dobrze (ponieważ cglib2 nie jest już wymagane; zamiast tego można użyć prostszego proxy JDK do interfejsu i Cobertura działa z tym dobrze).

Nie można jednak używać interfejsów z kontrolerami z adnotacjami (pojawi się błąd wykonania podczas próby użycia kontrolera w serwlecie) - nie mam rozwiązania do testów Cobertura + Spring, które autowire kontrolery.

Andrew Cooke
źródło
2

Miałem podobny problem: testy JUnit zakończyły się niepowodzeniem w Maven Surefire, ale przeszły pomyślnie w Eclipse, gdy korzystałem z biblioteki JUnit w wersji 4.11.0 z repozytorium pakietu SpringSource. W szczególności:

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

Następnie zastąpiłem go następującą wersją biblioteki JUnit 4.11 i wszystko działa dobrze.

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
</dependency>
Lukas Risko
źródło
To załatwiło sprawę dla mnie. Moje testy działały natychmiast po uruchomieniu Mavena z wiersza poleceń. Jednak w Eclipse musiałem zamknąć i ponownie otworzyć projekt przed uruchomieniem testów jednostkowych w oknie JUnit.
Marvo
1

Miałem dziś ten problem podczas testowania metody, która przekształciła obiekt zawierający Mapciąg znaków w JSON. Zakładam, że Eclipse i pewna wtyczka Maven korzystały z różnych JRE, które miały różne implementacje HashMapporządkowania lub coś w tym rodzaju, co spowodowało, że testy przebiegały przez Eclipse, a testy przebiegały przez pewny błąd ( assertEqualsnie powiodły się). Najłatwiejszym rozwiązaniem było skorzystanie z implementacji Map, która miała niezawodne porządkowanie.

Mitch
źródło
0

Nie musisz wstrzykiwać źródła danych w JpaTransactionManager, ponieważ EntityManagerFactory ma już źródło danych. Spróbuj wykonać następujące czynności:

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
   <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
Richard Kettelerij
źródło
Testy kończą się niepowodzeniem (z błędami) w Eclipse, jeśli usunę źródło danych z komponentu bean transactionManager.
Abhinav Sarkar
0

Zwykle, gdy testy kończą się zaćmieniem i kończą się niepowodzeniem z maven, jest to problem ze ścieżką klas, ponieważ jest to główna różnica między nimi.

Możesz więc sprawdzić ścieżkę klasy za pomocą maven -X test i sprawdzić ścieżkę klasy zaćmienia za pomocą menu lub w pliku .classpath w katalogu głównym projektu.

Czy jesteś na przykład pewien, że plik personalervice-test.xml znajduje się w ścieżce klas?

Bruno Thomas
źródło
Tak, ponieważ widzę dzienniki INFO z ładowania kontekstu Springa w konsoli podczas uruchomienia testowego Mavena.
Abhinav Sarkar
0

Pomogło mi to w rozwiązaniu problemu. Miałem podobne objawy w tym, że maven zawiódł, jednak testy junit działają dobrze.

Jak się okazuje, mój rodzic pom.xml zawiera następującą definicję:

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

W moim projekcie nadpisuję to, aby usunąć argLine:

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

Mam nadzieję, że pomoże to komuś w rozwiązywaniu problemów z pewną wtyczką.

mmastika
źródło
0

Miałem ten sam problem i rozwiązaniem dla mnie było umożliwienie Mavenowi obsługi wszystkich zależności, w tym lokalnych plików jar. Użyłem Maven do zależności online i ręcznie skonfigurowałem ścieżkę kompilacji dla zależności lokalnych. Dlatego Maven nie był świadomy zależności, które skonfigurowałem ręcznie.

Użyłem tego rozwiązania, aby zainstalować lokalne zależności jar w Maven:

Jak dodać lokalne pliki jar w projekcie Maven?

Bitango.me
źródło
0

W moim przypadku przyczyną był błąd w kodzie. Test opierał się na określonej kolejności elementów w a HashSet, która okazała się inna po uruchomieniu w Eclipse lub w Maven Surefire.

Robert Lill
źródło
-2

Najprawdopodobniej twoje pliki konfiguracyjne znajdują się w src / main / resources , podczas gdy muszą znajdować się w src / test / resources aby działały poprawnie w maven.

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

Odpowiadam na to po dwóch latach, bo nie mogłem znaleźć tutaj odpowiedzi i myślę, że jest to właściwa odpowiedź.

Miguel
źródło
Nie, jest odwrotnie. src/main/resourcesjest widoczny dla testów, ale src/test/resourcesnie jest widoczny dla kodu produkcyjnego.
Christoffer Hammarström
link, który dodałeś, mówi o zależnościach między projektami, a nie w ramach main / test w tym samym projekcie
eis