LazyinitializationException enquanto testam as classes de entidade de hibernato para uso na primavera, usando o testng

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

Pergunta

Na minha configuração de primavera, pedi que a sessão permanecesse aberta em meus pontos de vista:

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

No entanto, esse feijão obruecamente não considera meus testes de unidade de teste como uma visualização. ;-) Está tudo bem, mas existe um feijão semelhante para testes de unidade para que eu evite a temida LazyinitializationException enquanto testava unidade? Até agora, metade dos meus testes de unidade morrem por causa disso.

Meu teste de unidade normalmente se parece com o seguinte:

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



}

Eu tentei alterar a configuração () para isso:

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

Mas acredito que essa é a maneira errada de fazer isso, e eu mexendo na transação para testes posteriores. Existe algo como um OpenSessionIntestInterceptor, existem maneiras melhores de fazer isso, ou é a maneira de fazê -lo e, nesse caso, o que eu entendi mal sobre isso?

Felicidades

Nik

Foi útil?

Solução

Umm .. para não ser um assassino inteligente aqui, mas não é isso setUp() foi destinado a.

A idéia básica é fazer com que seus testes sejam auto-suficientes e reentrantes, o significado que você não deve depender do banco de dados com registros específicos nem deve alterar permanentemente o banco de dados em seu teste. O processo, portanto, é::

  1. Criar os registros necessários em setUp()
  2. Execute seus testes reais
  3. Limpe (se necessário) em tearDown()

(1), cada um (2) e (3) todos executam em transações separadas - daí o problema que você está recebendo com a LazyinitializationException. Jogada mockEntity = myEntityService.read(1); da configuração para os seus testes reais e ele desaparecerá; Use a configuração se precisar criar alguns dados de teste, não como suplemento direto para o seu teste individual.

Outras dicas

Eu uso o JUNIT para meus testes, então você precisa adaptar o exemplo a seguir para testar. Personnaly eu uso o springjunit4classrunner para vincular transações em uma classe de teste base:

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

E em "@Before", injeto um MockHttPervletRequest no requestContextholder:

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

     .......

Eu peguei as informações do manual

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top