序言:我在单元测试中一直在挣扎着LazyInitializationException,我很难理解它,正如我在Spring,TestNG和Spring 3中的Database Sessions和LazyInitializationException进行单元测试Hibernate时所看到的那样 使用TestNG在Spring中使用的实体类
为了能够清楚地提出我的问题,我在GitHub上创建了一个示例项目:http : //github.com/niklassaers/Sample-Spring3-App/ 在此示例项目中,我重现了我面临的问题在我的Spring3 / Hibernate3 / TestNG项目中。
问题是:我有两个单元测试,它们非常相似,使用相同的服务为相同的项目集合测试相同的类。一个运行,一个失败。为什么失败的人失败了?(或者,为什么运行中的一个不以相同的方式失败?)
这是失败的测试:
@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);
}
完整代码(http://github.com/niklassaers/Sample-Spring3-App/blob/master/src/tld/mydomain/sample/entities/test/FailingUserUnitTest.java)
这是运行测试:
@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());
}
}
}
完整代码(http://github.com/niklassaers/Sample-Spring3-App/blob/master/src/tld/mydomain/sample/entities/test/UserUnitTest.java)
下面是运行测试的控制台输出。我知道我将服务包装在TransactionProxyFactoryBean中(请参阅http://github.com/niklassaers/Sample-Spring3-App/blob/master/WebRoot/WEB-INF/App-Model.xml),在事务中,单元测试没有包装,使测试像视图一样。我已经使用OpenSessionInViewInterceptor“修复”了视图。但是我了解到,在从AbstractTransactionalTestNGSpringContextTests扩展的类中,用@Test注释的每个单元测试也应该包装在自己的事务中,并且实际上,我已经注释了这两个类以在完成每个测试后回滚事务。这就是为什么我对为什么一项测试失败而没有一项失败感到困惑的原因。有任何线索或解决方案吗?
您可以根据需要随意在GitHub上修改示例项目,所有代码都应该在其中,但是为了简单起见,我省略了jar文件。这是承诺的全部输出:
[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
===============================================
干杯
从@Test批注中删除timeOut = 1000。看来这导致测试在单独的线程中运行(如stacktrace所示,该异常是从ThreadPool引发的)。事务和SessionFactory绑定到主线程,而不绑定到测试运行程序的线程,这会导致此异常。
我已经运行了您的示例代码,并且已经进行了测试。将来,如果您将Maven2 pom.xml包含在您的依赖项中会很方便,那么对于那些试图编译您的代码的人来说,这样做起来会更容易。
问题内容: 序言: 我在单元测试中一直在挣扎着LazyInitializationException,我很难理解它,正如我在Spring,[TestNG和Spring3中的数据库会话以及在进行Hibernate单元测试时”使用TestNG对Spring中使用的Hibernate实体类进行单元测试时,出现LazyInitializationException”遇到的LazyInitializatio
本文向大家介绍 测试类型有哪些?相关面试题,主要包含被问及 测试类型有哪些?时的应答技巧和注意事项,需要的朋友参考一下 黑盒 白盒 灰盒
试着用TestNG运行我所有的cucumber测试。然而,我的套房没有找到。 当我将TestNG.xml文件作为TestNG运行时,未找到如下所示的测试
本文向大家介绍系统测试标准有哪些?相关面试题,主要包含被问及系统测试标准有哪些?时的应答技巧和注意事项,需要的朋友参考一下 不存在致命或严重级别的BUG 不存在优先级为P1的BUG 遗留问题不能大于总BUG数的8% 遗留问题不能明显影响用户使用
本文向大家介绍验收测试内容有哪些?相关面试题,主要包含被问及验收测试内容有哪些?时的应答技巧和注意事项,需要的朋友参考一下 合同验收测试、法规性验收测试、alpha测试、beta测试、确保实际效果与需求一致
问题内容: 我想获取某个Java进程的堆转储(可能的内存泄漏)。但是,当我启动jvisualvm工具时,看不到任何正在运行的Java进程。 我已经在Google上搜索了有关此内容,并且已经找到了几篇文章,说您必须使用启动jvisualvm工具时所使用的同一JDK运行Java进程,以便它能够看到它们。但是,据我所知,情况已经如此。我正在本地做所有事情(我可以远程访问机器)。 需要考虑的几件事: