2009-09-30 18 views
6

¿Cuál es la mejor manera de hacer pruebas unitarias con Spring? Supongo que la combinación TestNG & jmockit con Spring 3 no está nada mal, así que eso es lo que estoy haciendo en este momento, pero si estoy fuera del curso seleccionando las herramientas para mi proyecto Fresh Spring, díganmelo de inmediato. :-)TestNG y Spring 3

De todos modos, he creado una entidad que quiero probar, pero no estoy seguro de cómo ejecutar TestNG desde el contexto de Spring. He creado un simple clase de prueba

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() { 

    } 

} 

con applicationContext.xml la importación de granos para la creación de la capa del modelo y de negocios. En primer lugar, me gustaría utilizar el applicationContext.xml de Project/WebRoot/WEB-INF, mientras que la fuente para esta prueba reside en Project/src/com/mydomain/data/entities/test, pero creo que /applicationContext.xml me daría Projects/src, igual que classpath: ¿Es correcto?

Además, ahora que estoy usando las capas de modelo y negocio que utilizaría mi aplicación web, espero que se comporte de manera similar. Pero, cuando inicio TestNG en la prueba, que las EFS: org.hibernate.cfg.ExtendedMappings clase tiene org.hibernate.cfg.Mappings interfaz como superclase:

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é es y por qué estoy haciendo ¿esta? ¿Alguna pista?

Mi sessionFactory se parece a esto

<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

El soporte de prueba de SPring es para pruebas de integración, no para pruebas unitarias. Puede usar JUnit simple o TestNG para probar la unidad. Entonces, ¿qué pruebas estás tratando de lograr? – SteveD

Respuesta

5

Ahora el problema no parece estar relacionado con Spring o TestNG. La parte clave es:

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

¿Estás seguro de que tu CLASSPATH está bien? Es decir. tienes una versión compatible de los módulos de Hibernate y no hay repeticiones allí?

¿Qué pasa si se crea un simple análisis de TestNG que hace lo siguiente:

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

?

+0

Así que si doy la prueba un contexto vacío Puedo ejecutar una prueba que incluye Class.forName, que me da: java.lang.IncompatibleClassChangeError: class org.hibernate.cfg.ExtendedMappings tiene la interfaz org.hibernate.cfg.Mappings como superclase Pero cuando ejecuto el mismo en mi contexto de servlet, no tengo ningún problema. Y tienen la misma ruta de clase. – niklassaers

+0

Creo que el único lugar donde ExtendedMappings está definido en cualquiera de mis archivos jar está en hibernate-annotations.jar. – niklassaers

+0

Hmm, esto puede deberse a que estoy ejecutando Hibernate 3.5-beta1 con Hibernate-Annotations 3.4. Permítanme intentar y degradar a 3.4 y ver si están más alineados entonces :-) – niklassaers

1

consulte el capítulo sobre TestNG en la documentación de primavera:

+0

No se preocupe, solo escribí aquí después de leer "Spring TestContext Framework" en el manual de referencia de Spring 3 dos veces y de leer bastantes tutoriales – niklassaers

7

Su ckass prueba de necesidades para extender AbstractTestNGSpringContextTests. O si su código está probando el acceso a la base de datos, otra clase útil para extender es AbstractTransactionalTestNGSpringContextTests.

+0

Muchas gracias. La extensión de AbstractTestNGSpringContextTests hizo que cargue el contexto, pero me da una extraña excepción durante la inicialización. He actualizado mi pregunta con las excepciones que brinda a mi contexto – niklassaers

+0

Por favor, vota esto ya que es la respuesta a la pregunta original y es lo que estaba buscando (por ejemplo: Usar Spring con TestNG) –

0

Es posible que desee probar hibernate-annotations-3.5.0-Beta-1 ya que esto se alinea con hibernate-core-3.5.0-Beta-1.

Todavía obtengo el java.lang.IncompatibleClassChangeError a veces, ya que estoy tratando de usar la búsqueda de hibernación que está usando las anotaciones "antiguas".

Además, no estoy seguro de si está ejecutando JBoss, pero si lo hace, obtendrá este error con el núcleo 3.5.0.

+0

Si está utilizando hibernate-core-3.5.x, debe incluir las anotaciones (y entityManager) - ya no se requieren jar por separado hibernate https://www.hibernate.org/397.html – John

+0

Eso es Lo que pensé, pero aún necesito insertar anotaciones. Si observas las anotaciones de hibernación pom, tiene hibernate-core como dependencia. Lo que creo que hibernate significa es que los números de versión están alineados. O he estado bebiendo demasiada cerveza :) –

1

Para mí, este problema fue causado porque tenía diferentes versiones de hibernación incluidas, no porque un tercero las incluyera.Un barrido de su proyecto/poms para asegurarse de que su usuario desee utilizar solo una versión de hibernación, vale la pena.