Spring3 / Hibernate3 / TestNG: einige Tests LazyInitializationException geben, andere nicht
-
21-09-2019 - |
Frage
Das Vorwort: Ich bin struggeling mit LazyInitializationException in meiner Unit-Tests, und ich habe eine wirklich harte Zeit, meinen Kopf um es bekommen, wie man es von meinen Fragen sehen Datenbanksitzungen im Frühjahr , TestNG und Spring 3 und LazyInitializationException während Komponententests Hibernate Entitätsklassen für den Einsatz im Frühling, mit TestNG
Um meine Frage der Lage sein, klar zu stellen, die ich gemacht habe ein Beispielprojekt auf GitHub: http://github.com/niklassaers/Sample-Spring3-App/ in diesem Beispielprojekt reproduzieren ich die Probleme, die ich mit Blick auf bin in meinem Spring3 / Hibernate3 / TestNG Projekte.
Die Frage: Ich habe zwei Unit-Tests, ist sie ganz gleich, Test der gleiche Klasse für die gleiche Sammlung von Gegenständen des gleichen Dienst. Man läuft, ausfällt. Warum scheitern die fehlerhafte ein? (Oder, warum nicht der Lauf eines in der gleichen Art und Weise versagen?)
Hier ist der fehlerhafte Test:
@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);
}
vollständiger Code auf ( http://github.com/niklassaers/Sample-Spring3-App/blob/master/src/tld/mydomain/sample/entities/test/FailingUserUnitTest.java )
und hier ist der Lauftest:
@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());
}
}
}
vollständiger Code auf ( http://github.com/niklassaers/Sample-Spring3-App/blob/master/src/tld/mydomain/sample/entities/test/UserUnitTest.java )
Unten folgt die Konsolenausgabe meine Tests vom Laufen. Ich verstehe, dass ich die Dienste in einem TransactionProxyFactoryBean (siehe http://github.com/niklassaers/Sample-Spring3-App/blob/master/WebRoot/WEB-INF/App-Model.xml ), die sie in einem Lauf macht Transaktion und die Unit-Tests sind nicht gewickelt, den Test wie ein Blick zu machen. Die Ansichten, die ich habe „fest“ mit OpenSessionInViewInterceptor. Aber ich habe gelernt, dass jede Einheit Test mit @Test in einer Klasse mit Anmerkungen versehen, die von AbstractTransactionalTestNGSpringContextTests erstreckt sich auch in einer eigenen Transaktion gewickelt werden soll, und in die Tat habe ich beiden Klassen kommentiert die Transaktion rückgängig zu machen, nachdem jeder Test beendet ist. Deshalb habe ich doppelt bin verwirrt, warum ein Test fehlschlägt und man tut es nicht. Irgendwelche Hinweise oder Lösungen?
Sie können ferner das Beispielprojekt auf GitHub zu modifizieren, wie Sie möchten, ob der gesamte Code sollte es sein, aber ich habe die jar-Dateien der Einfachheit halber weggelassen. Hier ist die volle Leistung, wie versprochen:
[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
===============================================
Prost
Nik
Lösung
Nehmen Sie die timeOut = 1000 von der @Test Anmerkung. Es scheint, dass dies der Test in einem separaten Thread ausgeführt werden verursacht (wie durch die Stacktrace ersichtlich ist, wo die Ausnahme von einem Thread ausgelöst wird). Transaktionen und die Session werden an den Haupt-Thread gebunden, nicht an den Thread-Test Läufer, die diese Ausnahme verursacht.
Ich habe Ihren Beispielcode ausführen und habe den Test zur Arbeit gekommen. In Zukunft wäre es praktisch, wenn Sie einen Maven2 pom.xml mit Abhängigkeiten enthalten, so dass es leichter für diejenigen, die versuchen, den Code zu kompilieren, um so tatsächlich tun.