JUnit tests passent dans Eclipse, mais ne parviennent pas à Maven de Surefire
J'ai écrit quelques JUnit tests utilisant JUnit 4 et printemps-test de bibliothèques. Lorsque j'exécute les tests à l'intérieur de l'Éclipse puis exécutez fine et pass. Mais quand je les exécuter à l'aide de Maven (pendant le processus de génération), ils ne parviennent pas donner un printemps d'erreur lié. Je ne suis pas sûr de ce qui est à l'origine du problème, JUnit, Surefire ou au Printemps. Voici mon code de test, le printemps de la configuration et de l'exception que je reçois de Maven:
PersonServiceTest.java
package com.xyz.person.test;
import static com.xyz.person.util.FjUtil.toFjList;
import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;
import com.xyz.person.bo.Person;
import com.xyz.person.bs.PersonService;
import fj.Effect;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath*:personservice-test.xml" })
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false)
public class PersonServiceTest {
@Autowired
private PersonService service;
@Test
@Transactional
public void testCreatePerson() {
Person person = new Person();
person.setName("abhinav");
service.createPerson(person);
assertNotNull(person.getId());
}
@Test
@Transactional
public void testFindPersons() {
Person person = new Person();
person.setName("abhinav");
service.createPerson(person);
List<Person> persons = service.findPersons("abhinav");
toFjList(persons).foreach(new Effect<Person>() {
public void e(final Person p) {
assertEquals("abhinav", p.getName());
}});
}
}
personservice-test.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<import resource="classpath:/personservice.xml" />
<bean id="datasource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
lazy-init="true">
<property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver" />
<property name="url" value="jdbc:derby:InMemoryDatabase;create=true" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="datasource" />
<property name="persistenceUnitName" value="PersonService" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.DerbyDialect" />
<property name="showSql" value="true" />
<property name="generateDdl" value="true" />
</bean>
</property>
<property name="jpaPropertyMap">
<map>
<entry key="hibernate.validator.autoregister_listeners" value="false" />
<entry key="javax.persistence.transactionType" value="RESOURCE_LOCAL" />
</map>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="dataSource" ref="datasource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"
proxy-target-class="false" />
<bean id="beanMapper" class="org.dozer.DozerBeanMapper">
<property name="mappingFiles">
<list>
<value>personservice-mappings.xml</value>
</list>
</property>
</bean>
</beans>
Exception dans 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
- avez-vous des tout spécial de configuration du plugin surefire dans votre POM?
- Je n'ai pas de configuration pour surefire dans mon pompon
- Je suis venu à cet article car j'ai eu le même problème, mais dans mon cas j'ai utilisé une autre solution. Après l'activation de journaux de DÉBOGAGE sur mes tests, j'ai trouvé que le Framework Spring était à la recherche d'une ancienne base de données MongoDB nom, et ce nom a été mis dans une ancienne version d'un pot créé par un autre projet sur mon espace de travail (bien qu'il a été construit à plusieurs reprises avec le nouveau nom). Certains Maven Clen + de supprimer les bibliothèques sur mon .m2, suivi par Maven Installation de tous ces projets a résolu le problème. Bien qu'il n'y a pas de raison pour que le projet puisse regarder un vieux pot (il a été mis en cache quelque part, malheureusement)
Vous devez vous connecter pour publier un commentaire.
J'ai eu le même problème (JUnit tests ont échoué dans Maven Infaillible mais il passa dans Eclipse) et a réussi à le résoudre par la mise en forkMode à toujours dans le maven infaillible de configuration dans pom.xml:
Infaillible paramètres: http://maven.apache.org/plugins/maven-surefire-plugin/test-mojo.html
Édition (Janvier 2014):
Comme Peter Perháč souligné, le forkMode paramètre est obsolète depuis Infaillible 2.14. Début de Surefire 2.14 utiliser ce lieu:
Pour plus d'informations, voir Fourche Options et Parallèles d'Exécution des tests
J'ai soudain éprouvé cette erreur, et la solution pour moi a été de désactiver pour l'exécution de tests en parallèle.
Votre kilométrage peut varier, car je ne pouvais plus faible nombre de faillites d'essais en configuration infaillible pour exécuter des tests en parallèle par les classes.:
Comme je l'ai écrit d'abord, ce n'était pas assez pour mon test de suite, donc j'ai complètement désactivé parallèle par la suppression de la
<configuration>
section.J'ai eu un problème similaire, l'annotation
@Autowired
dans le code de test n'a pas de travail en vertu de l'aide de l'Maven en ligne de commande alors qu'il a bien fonctionné dans Eclipse. Je viens de mettre à jour mon JUnit version de 4,4 à 4,9 et le problème a été résolu.J'ai le même problème, mais avec IntelliJ IDEA + Maven + TestNG + ressort-test. (printemps-test est essentiel, bien sûr 🙂 )
Il a été résolu lorsque j'ai changer de config de maven-surefire-plugin pour désactiver l'exécution des tests en parallèle. Comme ceci:
Ce n'est pas exactement s'appliquent à votre situation, mais j'ai eu la même chose -- tests qui allait passer dans Eclipse a échoué lorsque l'objectif de test de Maven a été exécuté.
Il s'est avéré être un test plus tôt dans ma suite, dans un package différent. Ce qui m'a pris une semaine à résoudre!
D'un test précédent était de tester certaines Logback classes, et créé un Logback contexte à partir d'un fichier de configuration.
L'autre test est le test d'une sous-classe du Printemps SimpleRestTemplate, et d'une certaine façon, le plus tôt Logback contexte a eu lieu, avec le niveau de DEBUG. Cela a provoqué supplémentaire de passer des appels en RestTemplate de journal HttpStatus, etc.
C'est une autre chose à vérifier si l'on n'est jamais dans cette situation. J'ai résolu mon problème en injectant se moque de mon Logback de la classe de test, de sorte qu'aucune réelle Logback contextes ont été créés.
J'ai eu le même problème, mais le problème pour moi est que Java affirmations (par exemple, assert(num > 0)) n'ont pas été activé pour Eclipse, mais ont été activé lors de l'exécution de maven.
Donc en train jUnit tests à partir d'Eclipse ne pas attraper de déclencher l'erreur d'assertion.
C'est ce qui ressort lors de l'utilisation de jUnit 4.11 (contrairement à l'ancienne version que j'utilisais), parce qu'il affiche l'erreur d'assertion, par exemple
J'ai eu un problème similaire avec une cause différente et donc de la solution. Dans mon cas, j'ai effectivement eu une erreur où un objet singleton a été d'avoir un membre de la variable modifiée dans un non-thread-safe façon. Dans ce cas, suivant les réponses acceptées et de contourner les tests parallèles serait de ne masquer que l'erreur s'est en fait révélé par le test. Ma solution, bien sûr, est de fixer la conception de sorte que je n'ai pas ce mauvais comportement dans mon code.
L'exécution du Test résultat différent de
JUnit run
et demaven install
semble être un symptôme de plusieurs problèmes.La désactivation de fil réutilisation de l'exécution d'un test fait aussi de se débarrasser du symptôme dans notre cas, mais l'impression que le code n'est pas thread-safe est encore forte.
Dans notre cas, la différence est due à la présence d'un haricot qui a modifié le test de comportement. L'exécution du test JUnit seraient le résultat d'amende, mais l'exécution du projet
install
cible suite à l'échec d'un cas de test. Depuis qu'il a été le cas de test en cours de développement, il a été immédiatement suspect.Il en est résulté qu'un autre cas de test a l'instanciation d'un bean par le Ressort qui survive jusqu'à l'exécution du nouveau cas de test. Le haricot de présence a été de modifier le comportement de certaines classes et de produire le résultat a échoué.
La solution dans notre cas, était de se débarrasser de la fève, qui n'était pas nécessaire en premier lieu (encore un autre prix de la copier+coller pistolet).
Je suggère à tout le monde avec ce problème d'enquêter sur ce que la cause est. La désactivation de la fil de les réutiliser dans l'exécution des tests peut seulement cacher.
[Je ne suis pas sûr que c'est une réponse à la question d'origine, depuis la stacktrace ici est légèrement différente, mais il peut être utile à d'autres.]
Vous pouvez obtenir des tests d'échec, dans une Certaine lorsque vous exécutez également Cobertura (pour obtenir des rapports de couverture de code). C'est parce que Cobertura nécessite des procurations (pour mesurer le code de la consommation) et il y a une sorte de conflit entre ceux-ci et le Printemps des procurations. Cette seulement se produit quand le Printemps utilise cglib2, ce qui serait le cas si, par exemple, vous avez
proxy-target-class="true"
, ou si vous avez un objet proxy qui n'est pas d'implémenter des interfaces.La normale correctif à ce problème est d'ajouter une interface. Ainsi, par exemple, DAOs devrait être interfaces, mis en œuvre par un DAOImpl classe. Si vous autowire sur l'interface, tout fonctionnera correctement (parce que cglib2 n'est plus requise; une simplification de la JDK proxy de l'interface peut être utilisée à la place et Cobertura fonctionne très bien avec cette).
Cependant, vous ne pouvez pas utiliser les interfaces avec annoté contrôleurs (vous obtiendrez une erreur d'exécution lorsque vous essayez d'utiliser le contrôleur dans un servlet) - je n'ai pas de solution pour Cobertura + Ressort des tests qui autowire contrôleurs.
J'ai eu un problème similaire: JUnit tests ont échoué dans Maven Infaillible mais il passa dans Eclipse lorsque j'ai utilisé JUnit version de bibliothèque 4.11.0 de SpringSource Bundle Repository. En particulier:
Alors je l'ai remplacé par la suite JUnit version de bibliothèque 4.11 et tout fonctionne bien.
J'ai eu ce problème aujourd'hui le test d'une méthode qui convertit un objet qui contenait une
Map
à une chaîne JSON. Je suppose Eclipse et Maven plugin surefire ont été à l'aide de différents Jre de différentes implémentations deHashMap
de la commande ou quelque chose, qui a causé l'exécution des tests par le biais de l'Éclipse à passer et à l'exécution des tests par le biais de surefire à l'échec (assertEquals
a échoué). La solution la plus simple était d'utiliser une mise en œuvre de la Carte qui avaient fiable de la commande.Vous n'avez pas besoin d'injecter une source de données dans la JpaTransactionManager depuis l'EntityManagerFactory dispose déjà d'une source de données. Essayez ce qui suit:
Généralement lorsque les tests passent dans eclipse et ne parviennent pas avec maven, il est un classpath problème, parce que c'est la principale différence entre les deux.
De sorte que vous pouvez vérifier le classpath avec maven -X tester et de vérifier le classpath de l'eclipse via les menus ou dans le .classpath fichier dans la racine de votre projet.
Êtes-vous sûr par exemple que personservice-test.xml est dans le classpath ?
Cela m'a aidé dans le dépannage de mon problème. J'ai eu des symptômes similaires dans qui maven manquerait cependant l'exécution de tests junit fonctionne très bien.
Il s'avère que mes parent pom.xml contient la définition suivante:
Et dans mon projet, je le remplacer pour supprimer le argLine:
J'espère que cela va aider quelqu'un dans le dépannage plugin surefire.
<forkMode>
DEPRECATED depuis la version 2.14. UtilisationforkCount
etreuseForks
à la place."J'ai eu le même problème, et la solution pour moi a été de permettre à Maven pour gérer toutes les dépendances, y compris les locaux des bocaux. J'ai utilisé Maven en ligne de dépendances, et configuré de construire un chemin manuellement pour les dépendances locales.
Ainsi, Maven n'était pas au courant de l'dépendances, j'ai configuré manuellement.
J'ai utilisé cette solution pour installer le local pot de dépendances dans Maven:
Comment faire pour ajouter les fichiers jar dans le projet maven?
Il est plus probable que vos fichiers de configuration sont dans src/main/resources, alors qu'ils doivent être, en vertu de src/test/resources pour fonctionner correctement sous maven.
https://cwiki.apache.org/UIMA/differences-between-running-unit-tests-in-eclipse-and-in-maven.html
Je vais répondre à cet après deux ans parce que je n'arrivais pas à trouver cette réponse ici, et je pense que c'est la bonne.
src/main/resources
est visible pour les tests, maissrc/test/resources
n'est pas visible pour le code de production.