복붙노트

[SPRING] Spring Boot @WebIntegrationTest 및 TestRestTemplate - 테스트 트랜잭션을 롤백 할 수 있습니까?

SPRING

Spring Boot @WebIntegrationTest 및 TestRestTemplate - 테스트 트랜잭션을 롤백 할 수 있습니까?

스프링 데이터 레스트 (Spring Data Rest)가있는 스프링 부트 애플리케이션이 있고 통합 테스트에서 TestWindTemplate과 함께 @WebIntegrationTest를 사용합니다. 테스트의 기본 클래스는 다음과 같습니다.

@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles(profiles = "test")
@SpringApplicationConfiguration(classes = Application.class)
@Transactional
@TransactionConfiguration
@WebIntegrationTest("server.port: 0")
public abstract class IntegrationTest {

   ...

}

TestRestTemplate을 사용하여 리소스에 대한 POST 요청을 수행하여 엔티티 생성을 테스트했습니다. 문제는 내 테스트가 트랜잭션으로 구성되어 있어도 데이터베이스에서 엔티티를 유지하는 트랜잭션이 롤백되지 않으므로 엔티티가 테스트 후에 데이터베이스에 남아 있다는 것입니다. 테스트에서 롤백되는 트랜잭션이 엔티티를 지속시키는 동일한 트랜잭션이 아니기 때문에 이해가됩니다.

이제 내 질문은 테스트 메서드에서 RestTemplate을 통해 만들어진 요청에 의해 트리거 된 트랜잭션을 롤백 할 수있는 방법이 있습니까?

해결법

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

    1.아니요. 배포 된 응용 프로그램에서 관리하는 트랜잭션을 롤백 할 수 없습니다.

    아니요. 배포 된 응용 프로그램에서 관리하는 트랜잭션을 롤백 할 수 없습니다.

    @WebIntegrationTest와 @SpringApplicationConfiguration으로 테스트 클래스에 주석을 달아 봄으로써, Spring Boot는 내장 된 Servlet 컨테이너를 시작하고 그 안에 애플리케이션을 전개 할 것이다. 따라서 테스트 및 응용 프로그램은 두 가지 다른 프로세스에서 실행됩니다.

    Spring TestContext Framework는 테스트 관리 트랜잭션 만 관리합니다. 따라서 테스트 클래스에 @Transactional이 존재하면 다른 프로세스에있는 것이 아니라 로컬 테스트 관리 트랜잭션에만 영향을줍니다.

    다른 사람이 이미 언급했듯이 일단 테스트가 완료되면 데이터베이스의 상태를 다시 설정하는 것이 좋습니다. 이를 위해 몇 가지 옵션이 있습니다. 자세한 내용은 참조 설명서의 SQL 스크립트 실행 섹션을 참조하십시오.

    문안 인사,

    Sam (Spring TestContext Framework 작성자)

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

    2.TestRestTemplate 또는 RestTemplate을 사용하는 대신 MockMvc를 사용할 수 있습니다. 이 경우 @Transactional은 데이터 변경 사항을 롤백합니다.

    TestRestTemplate 또는 RestTemplate을 사용하는 대신 MockMvc를 사용할 수 있습니다. 이 경우 @Transactional은 데이터 변경 사항을 롤백합니다.

    POST 작업을 위해 @RestController의 로직을 테스트한다면, MockMvc 만 있으면 충분합니다. 테스트에 필터가 포함 된 경우 TestRestTemplate을 사용해야 할 가능성이 큽니다. 이 경우 다른 사람들이 지적했듯이 테스트가 끝나면 데이터베이스의 테스트 데이터를 다시 설정해야합니다.

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

    3.나는 우리의 1300+ 통합 테스트가 +70 분이 걸렸고 실행 가능하지만 저수준 배관을 통해 최근에 이것을 필요로했습니다.

    나는 우리의 1300+ 통합 테스트가 +70 분이 걸렸고 실행 가능하지만 저수준 배관을 통해 최근에 이것을 필요로했습니다.

    테스트 케이스와 부트 서버의 메모리가 공유됨에 따라 하나의 연결 만 관리하고 getConnection () 호출자에게 반환하는 DataSource 구현을 작성하는 중입니다. 연결 자체는 실제 연결에 대한 래퍼 역할을하는 Connection 구현입니다. 그런 다음 데이터 소스가 @SpringBootTest 구성에 추가됩니다.

    여기에 코드를 게시하지 않겠습니다 (회사 자산), 여기에 주요 내용이 있습니다.

    DataSource는 Connection 래퍼를 정적 필드로 유지 관리합니다. dataSource.getConnection ()시 모든 "차용 자"에 대한 카운터가 증가합니다. connection.close ()시,이 카운터는 감소합니다. 0이되면 테스트 케이스가 종료되고 트랜잭션이 롤백 될 수 있음을 의미합니다.

    고려해야 할 1 가지 잡동사니가 있으며 이는 스프링의 트랜잭션 관리입니다. 트랜잭션 롤백을 에뮬레이션해야합니다. 이렇게하려면 모든 connection.open ()에서 savepoint (connection.setSavePoint ())를 만들고 LinkedList에 푸시합니다. Ony 모든 connection.rollback (), 나는 그것을 스택에서 팝하고 connection.rollback (savePoint)을 수행합니다.

    @BeforeAll ()에서 db를 생성해야하기 때문에 커밋 기능을 사용할 수 있도록 해킹해야했습니다. 필자는 테스트 케이스에서 @Transactional에 의존하지 않지만 추상 부모의 @Before / @After 메소드에서 dataSource.getConnection / connection.close ()를 호출하여 트랜잭션 경계를 표시합니다.

    그것은 가장 좋은 해결책은 아니지만 테스트 시간을 70 분에서 30 분으로 줄였습니다 (테스트를 녹색으로 유지하면서). 이는 좋은 승리입니다.

    희망이 사람을 도움이됩니다.

  4. from https://stackoverflow.com/questions/29698291/spring-boot-webintegrationtest-and-testresttemplate-is-it-possible-to-rollbac by cc-by-sa and MIT license