복붙노트

[SPRING] JUnit 테스트는 항상 트랜잭션을 롤백합니다.

SPRING

JUnit 테스트는 항상 트랜잭션을 롤백합니다.

응용 프로그램 DAO에 대해 간단한 JUnit 테스트를 실행하고 있습니다. 문제는 내가 항상 얻는다는 것이다.

javax.persistence.RollbackException: Transaction marked as rollbackOnly

JUnit 테스트는 다음과 같습니다.

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

보시다시피이 메서드를 롤백하지 않도록 분명히 선언하고 있습니다.

Spring JUnit 지원은 언제나 롤백을 true로 설정합니까?

미리 감사드립니다.

해결법

  1. ==============================

    1.예상대로 작동하지만 테스트중인 클래스에서 다른 트랜잭션을 열거 나 어딘가에 다른 기능 또는 버그가있을 수 있습니다.

    예상대로 작동하지만 테스트중인 클래스에서 다른 트랜잭션을 열거 나 어딘가에 다른 기능 또는 버그가있을 수 있습니다.

    이 주석은 충분해야합니다.

    @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 Spring 레퍼런스 9.3.5.4 트랜잭션 관리

  2. ==============================

    2.데이터베이스를 변경하고 수정 사항을 유지하는 테스트가 필요한 것은 이상한 일입니다. 테스트는 직각이라고 가정합니다. 테스트는 다른 테스트에 의존하지 않습니다. 게다가, 테스트는 테스트 순서와 독립적이며 멱등수라고 가정합니다.

    데이터베이스를 변경하고 수정 사항을 유지하는 테스트가 필요한 것은 이상한 일입니다. 테스트는 직각이라고 가정합니다. 테스트는 다른 테스트에 의존하지 않습니다. 게다가, 테스트는 테스트 순서와 독립적이며 멱등수라고 가정합니다.

    따라서 setUp () 메서드에서 데이터베이스를 변경하고 tearDown () 메서드에서 변경 내용을 롤백하려는 경우 테스트를 위해 테스트 데이터베이스에 값이 좋은 테스트 데이터베이스를 설정해야합니다.

    어쩌면 나는 여기에서 뭔가를 놓치고 있지만 보통 당신은 그것을 원하지 않아야합니다.

  3. ==============================

    3.주석 롤백을 추가하고 플래그를 false로 설정하면됩니다.

    주석 롤백을 추가하고 플래그를 false로 설정하면됩니다.

       @Test
       @Rollback(false)
    
  4. ==============================

    4.공식 문서에서 :

    공식 문서에서 :

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

  5. ==============================

    5.나는 랄프의 대답에 동의한다.

    나는 랄프의 대답에 동의한다.

    Propagation.REQUIRES_NEW는 새 트랜잭션을 만들고 이것은 아마도 테스트가 실행중인 주요 트랜잭션 경로와 일치하지 않습니다.

    간단한 경험으로 주석 @Transactional은 모든 단일 테스트를 실행해야하는 트랜잭션 컨텍스트를 정의하고 Ralph에 표시된 것처럼 현재의 특정 롤백 절을 위임합니다.

    Ralph의 대답은 유용하며 동시에 Snicolas의 대답은 테스트 컨텍스트를 관리하는 특별한 경우에 관한 것입니다. 멱등 원은 통합 및 자동 테스트에 기본이지만이를 구현하는 다른 방법이어야합니다. 문제는 어떤 종류의 방법이 있습니까? 그리고 그 방법들은 어떤 행동을합니까?

       [...]
       @Transactional
    
       public class Test {
    
       @Test
       @Rollback(false)
       public void test() {
    
       [...]
    

    간단하고 질문에 일관된 방식입니다 :)

  6. ==============================

    6.

    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...
          }
    
  7. from https://stackoverflow.com/questions/9817388/junit-tests-always-rollback-the-transactions by cc-by-sa and MIT license