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>
그러나이 Bean은 TestNG 단위 테스트를보기로 간주하지 않습니다. ;-) 괜찮지 만 단위 테스트를하는 동안 끔찍한 LazyInitializationException을 피할 수 있도록 단위 테스트와 비슷한 Bean이 있습니까? 지금까지 내 단위 테스트의 절반은 그로 인해 죽습니다.
내 단위 테스트는 일반적으로 다음과 같습니다.
@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 ()를 이것으로 변경하려고 시도했습니다.
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);
}
그러나 나는 이것이 잘못된 방법이라고 생각하며, 나중에 테스트를 위해 거래를 엉망으로 만들었습니다. OpenSessionIntestestinterceptor와 같은 것이 있습니까,이 작업을 수행하는 더 좋은 방법이 있습니까, 아니면이를 수행하는 방법이 있습니까?
건배
닉
해결책
음 .. 여기서 똑똑한 사람이 아니라 setUp()
의도 된 것입니다.
기본 아이디어는 테스트를 자급 자족하고 재진입함으로써 특정 레코드가있는 데이터베이스에 의존해서는 안되며 테스트에서 데이터베이스를 영구적으로 변경해서는 안됩니다. 따라서 프로세스는 다음과 같습니다.
- 필요한 레코드를 작성하십시오
setUp()
- 실제 테스트를 실행하십시오
- 청소 (필요한 경우)
tearDown()
(1), 각 (2) 및 (3)은 모두 별도의 거래에서 실행되므로 LazyInitializationException에서 얻는 문제입니다. 이동하다 mockEntity = myEntityService.read(1);
설정에서 실제 테스트로 가면 사라집니다. 개별 테스트에 직접 보충되지 않고 일부 테스트 데이터를 작성 해야하는 경우 설정을 사용하십시오.
다른 팁
테스트에 Junit을 사용하므로 TestNG에 다음 예제를 조정해야합니다. Personaly 나는 기본 테스트 클래스에서 트랜잭션을 바인딩하기 위해 SpringJunit4classRunner를 사용합니다.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:/applicationContext-struts.xml")
@TransactionConfiguration(transactionManager = "transactionManager")
@Transactional
public abstract class BaseTests {
그리고 "@before"에서, 나는 requestContexTholder에 mockhttpservletrequest를 주입합니다.
@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);
.......
나는 정보를 가져 왔습니다 수동