web-dev-qa-db-fra.com

Les tests JUnit annulent toujours les transactions

J'exécute un simple test JUnit sur un DAO d'application. Le problème est que je reçois toujours:

javax.persistence.RollbackException: Transaction marked as rollbackOnly

Le test JUnit est:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:com/my/app/context.xml"}
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false)
@Transactional
public class PerformanceTest {

    @Test
    @Transactional(propagation= Propagation.REQUIRES_NEW)
    @Rollback(false)
    public void testMsisdnCreationPerformance() {
        // Create a JPA entity

        // Persist JPA entity
    }
}

Comme vous pouvez le constater, je déclare clairement que cette méthode ne doit pas être annulée.

La prise en charge de Spring JUnit définit-elle toujours la restauration sur true?

Merci d'avance,

23
Juan

Cela devrait fonctionner, comme vous l’attendez, mais vous pouvez peut-être ouvrir une autre transaction au sein de votre classe sous test ou vous avez une autre fonctionnalité/bogue quelque part.

Btw ces annotations devraient être enougth:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:com/my/app/context.xml"}
@Transactional
public class PerformanceTest {

    @Test
    @Rollback(false)
    public void testMsisdnCreationPerformance() {
        // Create a JPA entity

        // Persist JPA entity
    }
}

@See Référence au chapitre Chapitre 9.3.5.4 Gestion des transactions

46
Ralph

Il est étrange de vouloir un test qui modifie votre base de données et conserve la modification . Les tests sont supposés être orthogonaux: aucun test ne dépend d’un autre. De plus, les tests sont supposés être indépendants de leur ordre, et même idempotent .

Vous devez donc soit modifier votre base de données dans votre méthode setUp() et annuler la modification de votre méthode tearDown(), soit vous souhaitez configurer une base de données de test contenant de bonnes valeurs pour les tests. 

Peut-être que je manque quelque chose ici, mais généralement, vous ne devriez pas vouloir cela.

11
Snicolas

Ajoutez simplement une annotation Annulation et définissez l'indicateur sur false.

   @Test
   @Rollback(false)
10
grep

De la documentation officielle:

Par défaut, les transactions de test seront automatiquement annulées après achèvement du test; Cependant, les validations et les annulations transactionnelles Le comportement peut être configuré de manière déclarative via @Commit et @Rollback annotations

https://docs.spring.io/spring/docs/current/spring-framework-reference/html/integration-testing.html#integration-testing-annotations

@Commit indique que la transaction pour une méthode de test transactionnelle doivent être validés une fois la méthode de test terminée. @Commit peut être utilisé en remplacement direct de @Rollback (false) afin de générer davantage transmettre explicitement l'intention du code.

3
harryssuperman
I use Junit5, both commit and rollback(false) works with me.

    @ExtendWith(SpringExtension.class)
    @SpringBootTest
    @Transactional
    public class MyIntegrationTest {

      @Test
      @DisplayName("Spring Boot Will Rollback Data, " +
      "Can Disable it By Add @Commit Or @Rollback(false) Annotation")
      //@Commit
      //@Rollback(false)
      public void test() throws Exception {
       //your test codes here...
      }
0
Vicky

Je suis d'accord avec la réponse de Ralph.

La Propagation.REQUIRES_NEW crée une nouvelle transaction, qui ne correspond probablement pas à la route transactionnelle principale dans laquelle le test est exécuté.

Dans mon expérience simple, l'annotation @Transactional va correctement définir le contexte transactionnel dans lequel chaque test doit être exécuté, en déléguant à celui-ci la clause spécifique actuelle Rollback (comme l'a montré Ralph).

La réponse de Ralph est utile et, dans le même temps, la réponse de Snicolas concerne un cas particulier de gestion du contexte de tests . Le idempotence est fondamental pour l'intégration et les tests automatiques, mais doit présenter différentes manières de les implémenter . La question est, quel genre de méthodes avez-vous? Et quel comportement ces méthodes ont-elles?

   [...]
   @Transactional

   public class Test {

   @Test
   @Rollback(false)
   public void test() {

   [...]

Est-ce simple, question-cohérente façon :)

0
AL3X