LazyInitializationException, в то время как единопроцестные классы Hibernate Entity для использования в пружине, используя Testng

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

Вопрос

В моей весенней конфигурации я попросил, чтобы сеанс оставался открытым в моих взглядах:

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

Тем не менее, этот бобовый, ужасно не рассматривает мои тесты на Testng модуль как представление. ;-) Все в порядке, но есть ли похожий бобы для модульных тестов, так что я избегаю страшного лейзинициализации Exception во время тестирования на единицу? Пока что половина моих модульных тестов умирает из -за этого.

Мой модульный тест обычно выглядит так:

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



}

Я пытался изменить настройку () на это:

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

Но я считаю, что это неправильный способ сделать это, и я испорчу транзакцию для последующих тестов. Есть ли что -то вроде OpenSessionIntEnterceptor, есть ли это лучшие способы сделать это, или это способ сделать это, и в этом случае я неправильно понял в этом?

Ваше здоровье

Ник

Это было полезно?

Решение

Ммм .. не быть здесь умным, но это не то, что setUp() был предназначен для.

Основная идея состоит в том, чтобы ваши тесты были самодостаточными и повторными значениями, что вы не должны зависеть от базы данных, имеющих определенные записи, и не должны постоянно изменять базу данных в своем тесте. Процесс, таким образом, заключается в:

  1. Создайте любые необходимые записи в setUp()
  2. Запустите свои фактические тесты
  3. Очистить (при необходимости) в tearDown()

(1), каждый (2) и (3) все работают в отдельных транзакциях - отсюда и проблема, которую вы получаете с LazyInitializationException. Шаг mockEntity = myEntityService.read(1); от настройки в ваши фактические тесты, и он исчезнет; Используйте настройку, если вам нужно создать некоторые тестовые данные, а не как прямое дополнение к вашему отдельному тесту.

Другие советы

Я использую Junit для своих тестов, поэтому вам нужно адаптировать следующий пример к Testng. Personnaly Я использую Springjunit4classrunner для связывания транзакций в базовом тестовом классе:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:/applicationContext-struts.xml")
@TransactionConfiguration(transactionManager = "transactionManager")
@Transactional
public abstract class BaseTests {

И в «@before» я вводил MockhttpservletRequest в запрос ConctexTholder:

@Before
public void prepareTestInstance() throws Exception {
    applicationContext.getBeanFactory().registerScope("session", new SessionScope());
    applicationContext.getBeanFactory().registerScope("request", new RequestScope());
    MockHttpServletRequest request = new MockHttpServletRequest();

    ServletRequestAttributes attributes = new ServletRequestAttributes(request);
    RequestContextHolder.setRequestAttributes(attributes);

     .......

Я взял информацию из руководство

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top