Spring3 / Hibernate3 / TestNG: certains tests donnent LazyInitializationException, certains ne le font pas

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

Question

La préface: Je suis struggeling avec LazyInitializationException dans mes tests unitaires, et j'ai beaucoup de mal à obtenir ma tête autour d'elle, comme vous pouvez le voir sur mes questions Sessions de base de données au printemps , TestNG et Spring 3 et LazyInitializationException tandis que les classes d'entités tests unitaires Hibernate pour une utilisation au printemps, en utilisant TestNG

Pour être en mesure de poser ma question clairement, je l'ai fait un exemple de projet sur GitHub: http://github.com/niklassaers/Sample-Spring3-App/ dans cet exemple de projet, je reproduis les problèmes que je suis confronté à mes projets Spring3 / Hibernate3 / de TestNG.

La question: J'ai deux tests unitaires, ils sont tout à fait semblables, tester la même classe pour la même collection d'objets en utilisant le même service. L 'un court, on échoue. Pourquoi l'échec d'un échec? (Ou, pourquoi ne pas en cours d'exécution d'un échec de la même manière?)

Voici le test à défaut:

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

code complet à ( http://github.com/niklassaers/Sample-Spring3-App/blob/master/src/tld/mydomain/sample/entities/test/FailingUserUnitTest.java )

et est ici le test en cours d'exécution:

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

code complet à ( http://github.com/niklassaers/Sample-Spring3-App/blob/master/src/tld/mydomain/sample/entities/test/UserUnitTest.java )

suivante En dessous de la sortie de la console d'exécuter mes tests. Je comprends que j'ai les services enveloppés dans un TransactionProxyFactoryBean (voir http://github.com/niklassaers/Sample-Spring3-App/blob/master/WebRoot/WEB-INF/App-Model.xml ), qui les fait courir dans une transaction, et les tests unitaires ne sont pas emballés, ce qui rend le test comme une vue. Les points de vue que j'ai « fixe » avec OpenSessionInViewInterceptor. Mais je l'ai appris que chaque test unitaire annotée avec @Test dans une classe qui va de AbstractTransactionalTestNGSpringContextTests devrait également être enveloppé dans sa propre transaction, et en fait je l'ai annotés les deux classes pour annuler la transaction après chaque test est terminé. Voilà pourquoi je suis doublement perplexe quant à la raison pour laquelle un test échoue et on n'a pas. Des indices ou des solutions?

Ne hésitez pas à modifier le projet exemple GitHub comme bon vous semble, tout le code doit être là, mais je l'ai laissé les fichiers JAR pour des raisons de simplicité. Voici le résultat complet comme promis:

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

Vive

Nik

Était-ce utile?

La solution

Supprimer le délai d'attente = 1000 de l'annotation @Test. Il semble que cela est à l'origine du test pour être exécuté dans un thread séparé (comme on le voit par le stacktrace, où l'exception est levée à partir d'un ThreadPool). Les transactions et la SessionFactory sont liées au thread principal, pas au fil du coureur de test, ce qui est à l'origine de cette exception.

J'ai exécuter votre code d'exemple et ont obtenu le test au travail. À l'avenir, il serait utile si vous avez inclus un pom.xml Maven2 avec vos dépendances afin qu'il soit plus facile pour ceux qui tentent de compiler votre code pour faire réellement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top