Question

J'utilise Testng pour tester la persistance des modules de printemps (JPA + Hibernate) en utilisant AbstractTransactionalTestNGSpringContextTests comme une classe de base. Toutes les parties importantes @Autowired, @TransactionConfiguration, travail @Transactional très bien.

Le problème vient quand je suis en train de réaliser des essais en fils parallèles avec threadPoolSize = x, y invocationCount = annotation TestNG.

WARNING: Caught exception while allowing TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener@174202a] 
to process 'before' execution of test method [testCreate()] for test instance [DaoTest] java.lang.IllegalStateException:
Cannot start new transaction without ending existing transaction: Invoke endTransaction() before startNewTransaction().
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.beforeTestMethod(TransactionalTestExecutionListener.java:123)
at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:374)
at org.springframework.test.context.testng.AbstractTestNGSpringContextTests.springTestContextBeforeTestMethod(AbstractTestNGSpringContextTests.java:146)

... Quelqu'un at-il fait face à ce problème?

Voici le code:

@TransactionConfiguration(defaultRollback = false)
@ContextConfiguration(locations = { "/META-INF/app.xml" })
public class DaoTest extends AbstractTransactionalTestNGSpringContextTests {

@Autowired
private DaoMgr dm;

@Test(threadPoolSize=5, invocationCount=10)
public void testCreate() {
    ...
    dao.persist(o);
    ...
}
...

Mise à jour: Il semble que AbstractTransactionalTestNGSpringContextTests maintient transaction uniquement pour thread principal lorsque tous les autres fils de test ne reçoivent pas leur propre instance de transaction. La seule façon de résoudre ce AbstractTestNGSpringContextTests est d'étendre et maintenir transaction par programme (au lieu d'annotation @Transactional) par chacune des méthodes (par exemple avec TransactionTemplate):

@Test(threadPoolSize=5, invocationCount=10)
public void testMethod() {
    new TransactionTemplate(txManager).execute(new TransactionCallbackWithoutResult() {
        @Override
        protected void doInTransactionWithoutResult(TransactionStatus status) {
            // transactional test logic goes here
        }
    }
}
Était-ce utile?

La solution

La transaction doit être démarré dans le même fil, voici plus de détails:

Spring3 / Hibernate3 / TestNG: certains tests donnent LazyInitializationException, certains ne

Autres conseils

Ne pensez-vous pas cela vient plutôt de fil org.springframework.test.context.TestContextManager ne pas être en sécurité (voir https://jira.springsource.org/browse/SPR-5863 )?

Je fait face à la même question quand je voulais lancer mes tests transactionnelles TestNG en parallèle et vous pouvez voir que le printemps essaie en fait de lier la transaction à droite de cette discussion.

Cependant cela échoue au hasard avec ce genre d'erreurs. Je tendis AbstractTransactionalTestNGSpringContextTests avec:

@Override
@BeforeMethod(alwaysRun = true)
protected synchronized void springTestContextBeforeTestMethod(
        Method testMethod) throws Exception {
    super.springTestContextBeforeTestMethod(testMethod);
}

@Override
@AfterMethod(alwaysRun = true)
protected synchronized void springTestContextAfterTestMethod(
        Method testMethod) throws Exception {
    super.springTestContextAfterTestMethod(testMethod);
}

(la clé étant la synchronisation ...)

et il travaille maintenant comme un charme. Je ne peux pas attendre pour le printemps 3.2 mais pour qu'il puisse être complètement parallized!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top