2009-09-30 8 views
6

Quelle est la meilleure façon de faire des tests unitaires avec Spring? Je suppose que la combinaison TestNG & jmockit avec Spring 3 n'est pas mauvaise, donc c'est ce que je fais en ce moment, mais si je choisis bien sûr les outils pour mon projet printanier, dites-le moi tout de suite. :-)TestNG et Spring 3

Quoi qu'il en soit, j'ai créé une entité que je veux tester, mais je ne suis pas sûr de savoir comment exécuter le TestNG à partir du contexte Spring. J'ai créé une classe de test simple

package com.mydomain.data.entities.test; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.ApplicationContext; 
import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; 
import org.testng.Assert; 
import org.testng.annotations.*; 

@ContextConfiguration(locations={"classpath:applicationContext.xml"}) 
public class SimpleTest extends AbstractTestNGSpringContextTests { 

    @Autowired 
    private ApplicationContext applicationContext; 

    @BeforeClass 
    protected void setUp() throws Exception { 
     Assert.assertNotNull(applicationContext); 
    } 

    @Test 
    public void testNothing() { 

    } 

} 

avec applicationContext.xml importation des haricots pour la mise en place de la couche de modèle et d'affaires. Tout d'abord, je voudrais utiliser le fichier applicationContext.xml de Project/WebRoot/WEB-INF, alors que la source de ce test réside dans Project/src/com/mydomain/data/entities/test, mais je crois que /applicationContext.xml me donnerait Projects/src, même chose que classpath: Est-ce correct? En outre, maintenant que j'utilise les couches de modèle et de gestion que mon application Web utiliserait, je devrais m'attendre à ce qu'elle se comporte de la même façon. Mais, quand je lance TestNG sur le test, il SAIS: org.hibernate.cfg.ExtendedMappings classe a org.hibernate.cfg.Mappings d'interface comme super-classe:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in URL [file:/Users/niklas/Documents/Eclipse/Project/WebRoot/WEB-INF/Project-Model.xml]: Invocation of init method failed; nested exception is java.lang.IncompatibleClassChangeError: class org.hibernate.cfg.ExtendedMappings has interface org.hibernate.cfg.Mappings as super class 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1393) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:511) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:449) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:289) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:286) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:192) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:352) 
    at org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludingAncestors(BeanFactoryUtils.java:266) 
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.detectPersistenceExceptionTranslators(PersistenceExceptionTranslationInterceptor.java:121) 
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.<init>(PersistenceExceptionTranslationInterceptor.java:77) 
    at org.springframework.dao.annotation.PersistenceExceptionTranslationAdvisor.<init>(PersistenceExceptionTranslationAdvisor.java:70) 
    at org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor.setBeanFactory(PersistenceExceptionTranslationPostProcessor.java:99) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(AbstractAutowireCapableBeanFactory.java:1414) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1381) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:511) 
    ... 38 more 
Caused by: java.lang.IncompatibleClassChangeError: class org.hibernate.cfg.ExtendedMappings has interface org.hibernate.cfg.Mappings as super class 
    at java.lang.ClassLoader.defineClass1(Native Method) 
    at java.lang.ClassLoader.defineClass(ClassLoader.java:700) 
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124) 
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:260) 
    at java.net.URLClassLoader.access$000(URLClassLoader.java:56) 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:195) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:188) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:319) 
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:330) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:254) 
    at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:399) 
    at org.hibernate.cfg.AnnotationConfiguration.createExtendedMappings(AnnotationConfiguration.java:187) 
    at org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:277) 
    at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1162) 
    at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:667) 
    at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:211) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1452) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1390) 
    ... 53 more 

Qu'est-ce et pourquoi j'obtiens ce? Des indices?

Mon sessionFactory ressemble à ceci

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="annotatedClasses"> 
     <list> 
     <!-- Entity classes from package com.mydomain.data.entities --> 
     </list> 
    </property> 
    <property name="hibernateProperties"> 
     <props> 
     <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> 
     <prop key="hibernate.show_sql">false</prop> 
     </props> 
    </property> 
    </bean> 
+0

La prise en charge des tests de SPring est destinée aux tests d'intégration et non aux tests unitaires. Vous pouvez utiliser JUnit ou TestNG pour les tests unitaires. Alors, quels tests essayez-vous réellement? – SteveD

Répondre

5

Maintenant, le problème ne semble pas être lié à Spring ou TestNG. La partie clé est:

java.lang.IncompatibleClassChangeError: class org.hibernate.cfg.ExtendedMappings has interface org.hibernate.cfg.Mappings as super class 

Êtes-vous sûr que votre CLASSPATH est OK? C'est à dire. vous avez une version compatible des modules Hibernate et pas de répétitions là-bas?

si vous créez un simple test TestNG qui effectue les opérations suivantes:

Class.forName("org.hibernate.cfg.ExtendedMappings"); 

?

+0

Donc, si je donne le test un contexte vide Je peux exécuter un test qui inclut Class.forName, ce qui me donne: java.lang.IncompatibleClassChangeError: class org.hibernate.cfg.ExtendedMappings a une interface org.hibernate.cfg.Mappings en super classe Mais quand je cours le même dans mon contexte de servlet, je n'ai pas de problème. Et ils ont le même classpath. – niklassaers

+0

Je crois que le seul endroit où ExtendedMappings est défini dans n'importe lequel de mes fichiers jar se trouve dans hibernate-annotations.jar. – niklassaers

+0

Hmm, c'est peut-être parce que je cours Hibernate 3.5-beta1 avec Hibernate-Annotations 3.4. Laissez-moi essayer et rétrograder à 3.4 et voir si elles sont plus alignées alors :-) – niklassaers

1

Consulter le chapitre sur TestNG dans la documentation du printemps:

+0

Ne vous inquiétez pas, j'ai seulement écrit ici après avoir lu "Spring TestContext Framework" dans le manuel de référence de printemps 3 deux fois et en lisant quelques tutoriels – niklassaers

7

Votre ckass test doit prolonger AbstractTestNGSpringContextTests. Ou si votre code teste l'accès à la base de données, une autre classe utile à étendre est AbstractTransactionalTestNGSpringContextTests.

+0

Merci beaucoup. Étendre AbstractTestNGSpringContextTests l'a fait charger le contexte, mais il me donne une exception étrange pendant l'initialisation. J'ai mis à jour ma question avec les exceptions qu'elle donne à mon contexte – niklassaers

+0

S'il vous plaît voter comme il est la réponse à la question d'origine et est ce que je cherchais (par exemple: Using Spring avec TestNG) –

0

Vous pouvez essayer hibernate-annotations-3.5.0-Beta-1 car il s'aligne avec hibernate-core-3.5.0-Beta-1.

Je reçois toujours l'erreur java.lang.IncompatibleClassChangeError, car j'essaie d'utiliser la recherche hibernate qui utilise les "anciennes" annotations.

En outre, vous ne savez pas si vous exécutez JBoss, mais si vous êtes, vous obtiendrez cette erreur avec le noyau 3.5.0.

+0

Si vous utilisez hibernate-core-3.5.x, il devrait inclure les annotations (et entityManager) - des bocaux séparés ne sont plus nécessaires selon hibernate https://www.hibernate.org/397.html – John

+0

Ce que je pensais, mais j'ai encore besoin de tirer des annotations. Si vous regardez hibernate-annotations pom, il a hibernate-core comme une dépendance. Ce que je pense qu'hibernate signifie, c'est que les numéros de version sont alignés. Ou ai-je bu trop de bière :) –

1

Pour moi ce problème a été causé parce que j'avais différentes versions d'hibernation incluses moi-même, pas à cause d'un tiers les incluant.Un balayage de votre projet/poms pour vous assurer que vous utilisez seulement une version d'hibernation en vaut la peine.