Domanda

La prefazione: Sto struggeling con LazyInitializationException nel mio test di unità, e ho un momento davvero difficile ottenere la mia testa intorno ad esso, come si può vedere dalle mie domande database in primavera , TestNG e Spring 3 e LazyInitializationException mentre unit test classi entità Hibernate per l'uso in primavera, utilizzando TestNG

Al fine di essere in grado di porre la mia domanda in modo chiaro, ho fatto un progetto di esempio su GitHub: http://github.com/niklassaers/Sample-Spring3-App/ in questo progetto di esempio, riporto i problemi che sto affrontando nei miei progetti / TestNG Spring3 / Hibernate3.

La domanda: Ho due test di unità, sono abbastanza simili, prova la stessa classe per la stessa collezione di oggetti che utilizzano lo stesso servizio. Si corre, uno non riesce. Perché la mancanza di uno falliscono? (O, perchè non l'esecuzione uno falliscono nello stesso modo?)

Ecco la prova di mancanza di:

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

completo di codice a ( http://github.com/niklassaers/Sample-Spring3-App/blob/master/src/tld/mydomain/sample/entities/test/FailingUserUnitTest.java )

e qui è il test di esecuzione:

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

completo di codice a ( http://github.com/niklassaers/Sample-Spring3-App/blob/master/src/tld/mydomain/sample/entities/test/UserUnitTest.java )

Di seguito l'uscita della console di correre i miei test. Capisco che ho i servizi avvolto in un TransactionProxyFactoryBean (vedi http://github.com/niklassaers/Sample-Spring3-App/blob/master/WebRoot/WEB-INF/App-Model.xml ), che li rende eseguite in un transazione, e l'unità di test non sono avvolte, rendendo il test come una vista. I punti di vista che ho "fisso" con OpenSessionInViewInterceptor. Ma ho imparato che ogni unit test annotato con @Test in una classe che si estende da AbstractTransactionalTestNGSpringContextTests dovrebbe anche essere avvolto nella propria transazione, e in effetti ho annotato entrambe le classi per eseguire il rollback della transazione dopo ogni test è terminato. È per questo che io sono doppiamente perplesso sul motivo per cui un test non riesce e non lo fa. Eventuali indizi o le soluzioni?

Sentitevi liberi di modificare il progetto di esempio a GitHub come meglio credi, tutto il codice dovrebbe essere lì, ma ho lasciato fuori i jar-file per semplicità. Ecco l'output completo come promesso:

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

Saluti

Nik

È stato utile?

Soluzione

Rimuovi il timeout = 1000 dal l'annotazione @Test. Sembra che questo sta causando il test da eseguire in un thread separato (come è evidente dalla StackTrace, dove l'eccezione viene generata da un ThreadPool). Transazioni e la SessionFactory sono legati al filo principale, non filo del corridore prova, che causa questa eccezione.

Ho eseguito il codice di esempio e hanno ottenuto la prova di lavorare. In futuro, sarebbe utile se hai incluso un pom.xml Maven2 con le dipendenze in modo che sia più facile per coloro che cercano di compilare il codice di fare effettivamente così.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top