LazyInitializationException,同时使用TestNG对Spring中使用的Hibernate实体类进行单元测试 [英] LazyInitializationException while unit-testing Hibernate entity classes for use in Spring, using TestNG

查看:211
本文介绍了LazyInitializationException,同时使用TestNG对Spring中使用的Hibernate实体类进行单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的Spring配置中,我已经要求会话在我的视图中保持打开状态:

In my Spring configuration, I've asked that the session should remain open in my views:

  <bean name="openSessionInViewInterceptor" class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
    <property name="sessionFactory" ref="sessionFactory"/>
    <property name="flushMode" value="0" />
  </bean> 

然而,这个bean似乎不认为我的TestNG单元测试是一个视图。 ;-)那没关系,但是单元测试是否有类似的bean,以便在单元测试时避免可怕的LazyInitializationException?到目前为止,我的一半单元测试因此而死。

However, this bean obiously doesn't consider my TestNG unit tests as a view. ;-) That's all right, but is there a similar bean for unit tests so that I avoid the dreaded LazyInitializationException while unit-testing? So far, half of my unit tests die because of it.

我的单元测试通常如下所示:

My unit test typically looks like this:

@ContextConfiguration({"/applicationContext.xml", "/applicationContext-test.xml"})
public class EntityUnitTest extends AbstractTransactionalTestNGSpringContextTests {

  @BeforeClass
  protected void setUp() throws Exception {
    mockEntity = myEntityService.read(1);
  }

  /* tests */

  @Test
  public void LazyOneToManySet() {
    Set<SomeEntity> entities = mockEntity.getSomeEntitySet();
    Assert.assertTrue(entities.size() > 0); // This generates a LazyInitializationException
  }



}

我尝试将setUp()更改为:

I've tried changing the setUp() to this:

private SessionFactory sessionFactory = null;

@BeforeClass
protected void setUp() throws Exception {
  sessionFactory = (SessionFactory) this.applicationContext.getBean("sessionFactory");
  Session s = sessionFactory.openSession();
  TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(s));

  mockEntity = myEntityService.read(1);
}

但我相信这是错误的做法,我弄得一团糟交易以后的测试。有没有像OpenSessionInTestInterceptor这样的东西,有没有更好的方法来做到这一点,或者是这样做的方式,在这种情况下我有什么误解呢?

but I believe this is the wrong way to go about it, and I mess the transaction up for later tests. Is there something like an OpenSessionInTestInterceptor, are there better ways of doing this, or is this the way to do it and in that case what have I misunderstood about it?

干杯

Nik

推荐答案

嗯...不要聪明 - 屁股在这里,但那不是 setUp()的目的。

Umm.. not to be a smart-ass here, but that's not what setUp() was intended for.

基本的想法是让你的测试自我充分和可重入意味着您不应该依赖具有特定记录的数据库,也不应该永久更改测试中的数据库。因此,该过程是:

The basic idea is to have your tests be self-sufficient and re-entrant meaning you should not depend on database having particular records nor should you permanently alter the database in your test. The process, thus, is to:


  1. setUp()中创建任何必要的记录

  2. 运行实际测试

  3. 清理(如果需要) tearDown()

  1. Create any necessary records in setUp()
  2. Run your actual tests
  3. Clean up (if needed) in tearDown()

(1),每个(2)和(3)都在不同的交易中运行 - 因此你遇到的问题LazyInitializationException中。将 mockEntity = myEntityService.read(1); 从setUp移动到您的实际测试中,它将消失;如果您需要创建一些测试数据,请使用setUp,而不是作为您个人测试的直接补充。

(1), each (2), and (3) all run in separate transactions - hence the problem you're getting with LazyInitializationException. Move mockEntity = myEntityService.read(1); from setUp into your actual test(s) and it will go away; use setUp if you need to create some test data, not as direct supplement to your individual test.

这篇关于LazyInitializationException,同时使用TestNG对Spring中使用的Hibernate实体类进行单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆