LazyInitializationException, в то время как единопроцестные классы Hibernate Entity для использования в пружине, используя Testng
-
20-09-2019 - |
Вопрос
В моей весенней конфигурации я попросил, чтобы сеанс оставался открытым в моих взглядах:
<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()
был предназначен для.
Основная идея состоит в том, чтобы ваши тесты были самодостаточными и повторными значениями, что вы не должны зависеть от базы данных, имеющих определенные записи, и не должны постоянно изменять базу данных в своем тесте. Процесс, таким образом, заключается в:
- Создайте любые необходимые записи в
setUp()
- Запустите свои фактические тесты
- Очистить (при необходимости) в
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);
.......
Я взял информацию из руководство