Spring3 / Hibernate3 / TestNG: algunas pruebas dan LazyInitializationException, algunos no lo hacen

StackOverflow https://stackoverflow.com/questions/1571017

Pregunta

El prefacio: estoy struggeling con LazyInitializationException en mis pruebas unitarias, y tengo un momento muy difícil conseguir mi cabeza alrededor de ella, como se puede ver en mis preguntas en Spring , TestNG y primavera 3 y LazyInitializationException mientras que la unidad de pruebas de clases de entidad de Hibernate para su uso en la primavera, utilizando TestNG

Con el fin de ser capaz de hacer mi pregunta con claridad, he hecho un proyecto de ejemplo en GitHub: http://github.com/niklassaers/Sample-Spring3-App/ en este proyecto de ejemplo, reproduzco los problemas que estoy enfrentando en mis proyectos / TestNG Spring3 / Hibernate3.

La pregunta: Tengo dos pruebas unitarias, que son bastante parecidos, probar la misma clase para el mismo conjunto de elementos utilizando el mismo servicio. Uno corre, uno falla. ¿Por qué fracasa el que no? (O, ¿por qué no la ejecuta una falla de la misma manera?)

Aquí está la prueba en su defecto:

@Test(timeOut=1000)
public void Roles() {
    User mockUser = userService.read(1);
    Assert.assertNotNull(mockUser);
    Assert.assertTrue(mockUser.isValid());
    Set<Role> roles = mockUser.getRoles();
    int size = roles.size();  // This line gives a LazyInitializationException
    Assert.assertTrue(size > 0);
}

código completo al ( http://github.com/niklassaers/Sample-Spring3-App/blob/master/src/tld/mydomain/sample/entities/test/FailingUserUnitTest.java )

y aquí está la prueba de funcionamiento:

@Test
public void Roles() {
    for(int i = 1; i <= 4; i++) {
        User user = userService.read(i);
        Assert.assertNotNull(user);
        Assert.assertTrue(user.isValid());
        Set<Role> roles = user.getRoles();
        Assert.assertTrue(roles.size() > 0); // This line does not give a LazyInitializationException
        for(Role r : roles) {
            Assert.assertNotNull(r.getName());
            for(User someUser : r.getUsers())
                Assert.assertNotNull(someUser.getName());
        }
    }
}

código completo al ( http://github.com/niklassaers/Sample-Spring3-App/blob/master/src/tld/mydomain/sample/entities/test/UserUnitTest.java )

A continuación sigue la salida de la consola de correr mis pruebas. Yo entiendo que tengo los servicios envueltos en una TransactionProxyFactoryBean (ver http://github.com/niklassaers/Sample-Spring3-App/blob/master/WebRoot/WEB-INF/App-Model.xml ), que hace correr en una de transacción, y las pruebas de unidad no se envuelven, haciendo la prueba como una vista. Los puntos de vista que he "fijo" con OpenSessionInViewInterceptor. Pero he aprendido que cada unidad de prueba anotado con @test en una clase que se extiende desde AbstractTransactionalTestNGSpringContextTests también debe ser envuelto en su propia transacción, y de hecho he anotado las dos clases de deshacer la transacción después de cada prueba se terminó. Es por eso que estoy doblemente desconcertado en cuanto a por qué una prueba falla y uno no lo hace. Alguna pista o soluciones?

No dude en modificar el proyecto de ejemplo en GitHub como mejor le parezca, todo el código debe estar allí, pero me he dejado fuera los archivos JAR-por razones de simplicidad. Aquí está la salida completa como prometió:

[Parser] Running:
  /Users/niklas/Documents/Eclipse/SampleProject/testng.xml

2009-10-15 10:16:16,066 [TestNGInvoker-Roles()] ERROR org.hibernate.LazyInitializationException - failed to lazily initialize a collection of role: tld.mydomain.sample.entities.User.roles, no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: tld.mydomain.sample.entities.User.roles, no session or session was closed
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380)
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372)
    at org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:119)
    at org.hibernate.collection.PersistentSet.size(PersistentSet.java:162)
    at tld.mydomain.sample.entities.test.FailingUserUnitTest.Roles(FailingUserUnitTest.java:33)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.testng.internal.MethodHelper.invokeMethod(MethodHelper.java:607)
    at org.testng.internal.InvokeMethodRunnable.runOne(InvokeMethodRunnable.java:49)
    at org.testng.internal.InvokeMethodRunnable.run(InvokeMethodRunnable.java:40)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:637)

===============================================
SampleAppSuite
Total tests run: 3, Failures: 1, Skips: 0
===============================================

Saludos

Nik

¿Fue útil?

Solución

Eliminar el tiempo de espera = 1,000 de la anotación @test. Parece que esto está causando que la prueba se ejecuta en un hilo separado (como es evidente por la StackTrace, donde la excepción desde un ThreadPool). Transacciones y la SessionFactory están unidos al hilo principal, no para el hilo de la corredor de prueba, que está causando esta excepción.

He ejecutar su código de ejemplo y han conseguido la prueba a trabajar. En el futuro, sería útil si añade una pom.xml Maven2 con sus dependencias para que sea más fácil para los que tratan de compilar el código para hacer realmente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top