복붙노트

[SPRING] Spring 트랜잭션 관리 테스트

SPRING

Spring 트랜잭션 관리 테스트

SpringContextTests를 사용하여 Dao 클래스를 테스트하고 싶습니다. 내 메서드 클래스에서 JUnit4와 통합 할 테스트 클래스를 만들기 위해 AbstractTransactionalJUnit4SpringContextTests를 확장했습니다. 또한 구성을 설정하고 @After의 @Before 및 tearDown에서 초기화 및 데이터베이스 정리를 수행했습니다. 내 테스트 수업이 완벽하게 작동합니다. 내 문제는 내가 테스트 클래스를 실행하고 데이터베이스가 데이터로 채워지면 원래 데이터가 롤백되지 않아 데이터베이스가 삭제된다는 것이다. @Before 메서드에서는 데이터베이스를 지우고 데이터를 채 웁니다. 데이터를 롤백 할 수 있다고 생각하지만 그렇지 않습니다. 누구든지 데이터베이스의 정보를 롤백하고 롤백하는 예제를 사이트에 올릴 수 있습니까? ADDONS : 내 테스트 메소드의 모든 데이터베이스 조작은 롤백됩니다. 그러나 @Before 메서드에서 super.deleteFromTables ( "person")을 실행해도 데이터베이스의 모든 이전 데이터가 롤백되지 않았습니다. Spring은 모든 CRUD 작업을 롤백하지만 트랜잭션이 롤백되지 않기 전에 데이터베이스를 정리합니다.

해결법

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

    1.제 질문에 답한 모든 분들께 감사드립니다. 나는 그 답변들로부터 많은 것을 배웠지 만 그것은 내 문제를 해결하지 못했습니다. 테스트 데이터가 트랜잭션 관리를하고 작업을 제대로 수행하고 있음을 알았습니다. 실수는 내 부분에 있습니다. DML 문 다음에 DDL 문을 실행할 때 자동으로 트랜잭션을 커밋한다는 데이터베이스 명령에 대한 교훈을 잊어 버렸습니다. 모든 레코드를 삭제 한 다음 DDL을 실행하여 DDL을 실행하면 자동 커밋이 발생하고 테이블의 모든 레코드가 영구적으로 삭제되는 테이블의 AUTO_INCREMENT가 변경됩니다. 그 시나리오를 수정하면 내 문제가 해결되었습니다.

    제 질문에 답한 모든 분들께 감사드립니다. 나는 그 답변들로부터 많은 것을 배웠지 만 그것은 내 문제를 해결하지 못했습니다. 테스트 데이터가 트랜잭션 관리를하고 작업을 제대로 수행하고 있음을 알았습니다. 실수는 내 부분에 있습니다. DML 문 다음에 DDL 문을 실행할 때 자동으로 트랜잭션을 커밋한다는 데이터베이스 명령에 대한 교훈을 잊어 버렸습니다. 모든 레코드를 삭제 한 다음 DDL을 실행하여 DDL을 실행하면 자동 커밋이 발생하고 테이블의 모든 레코드가 영구적으로 삭제되는 테이블의 AUTO_INCREMENT가 변경됩니다. 그 시나리오를 수정하면 내 문제가 해결되었습니다.

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

    2.가능한 원인들:

    가능한 원인들:

    예를 들어, 여기에 하나 (머리 상단, 컴파일되지 않음)

    public class DBTest extends AbstractTransactionalJUnit4SpringContextTests {
    
        @Autowired
        private SomeDAO _aBeanDefinedInMyContextFile;
    
        @Test
        public void insert_works() {
            assert _aBeanDefinedInMyContextFile.findAll() == 0;
            _aBeanDefinedInMyContextFile.save(new Bean());
            assert _aBeanDefinedInMyContextFile.findAll() == 1;
        }
    
    
    }
    

    키 포인트:

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

    3.나는 당신의 수업에 무엇이 잘못되었는지 확신하지 못합니다. 다음은 dbunit 및 spring 2.5에서 원하는 것을 수행하는 클래스의 추출입니다.

    나는 당신의 수업에 무엇이 잘못되었는지 확신하지 못합니다. 다음은 dbunit 및 spring 2.5에서 원하는 것을 수행하는 클래스의 추출입니다.

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations={
      "testContext.xml"})
    @TransactionConfiguration
    @Transactional
    public class SampleDAOTest {
    
        @Autowired
        private DataSource dataSource;
        @Autowired
        private SampleDAO sampleDAO;
    
        @Before 
        public void onSetUpInTransaction() throws Exception {
            //Populate Test data
            IDatabaseConnection dbUnitCon = new DatabaseConnection(DataSourceUtils.getConnection(dataSource), "DATASOURCE");
                //read in from a dbunit excel file of test data
            IDataSet dataSet = new XlsDataSet(new File("src/test/resources/TestData.xls"));
            DatabaseOperation.INSERT.execute(dbUnitCon, dataSet);
        }
    
    
        @Test
        public void testGetIntermediaryOrganisation() {
    
            // Test getting a user
            User object = sampleDAO.getUser(99L);
            assertTrue(object.getValue);
    
    
        }
    }
    

    이 방법의 장점 중 하나는 클래스를 확장 할 필요가 없다는 것입니다. 따라서 테스트를 위해 자신 만의 계층 구조를 가질 수 있습니다.

    @before 어노테이션을 사용하는 대신 현재 메소드를 계속 사용하려면 아래 메소드를 대체하고 거기에 설정 코드를 입력해야한다고 생각합니다.

    @Override
    public void onSetUpInTransaction() throws Exception {...}
    

    희망이 도움이

  4. ==============================

    4.당신의 질문을 피하면서, 당신은 당신이 테스트를 실행하기 위해 별도의 데이터베이스 인스턴스를 사용하는 것이 좋습니다. 그렇게하면 안전하게 깨끗하게 닦고 필요에 따라 테스트를 초기화 할 수 있습니다.

    당신의 질문을 피하면서, 당신은 당신이 테스트를 실행하기 위해 별도의 데이터베이스 인스턴스를 사용하는 것이 좋습니다. 그렇게하면 안전하게 깨끗하게 닦고 필요에 따라 테스트를 초기화 할 수 있습니다.

    내가 아는 한, 데이터베이스 테스트를위한 Spring 지원 클래스는 테스트에서 일어나는 일을 롤백 만하고, 테스트의 셋업과 분해에서는 일어나지 않습니다.

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

    5.혼란에 동의하십시오 - 자신의 데이터베이스 스키마에 대해 테스트를 실행해야합니다.

    혼란에 동의하십시오 - 자신의 데이터베이스 스키마에 대해 테스트를 실행해야합니다.

    이렇게하면 최대 절전 모드 속성을 'create-drop'으로 설정할 수 있습니다.

    See : 선택적인 Hibernate Config 속성들

    스 니펫의 예 :

    <bean id="sessionBean" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="hibernateProperties">
          <props>
            <prop key="hibernate.hbm2ddl.auto">create-drop</prop>
             ...etc
    
  6. ==============================

    6.이 남자가 테스트를 위해 결정화 된 db를 제안하는 것에 동의하지만, 채워진 db를 사용하면 안되는 이유가 없습니다. @Before와 @After 메서드는 트랜잭션 컨텍스트 내에서 실행되므로 변경해야합니다. 복구하다.

    이 남자가 테스트를 위해 결정화 된 db를 제안하는 것에 동의하지만, 채워진 db를 사용하면 안되는 이유가 없습니다. @Before와 @After 메서드는 트랜잭션 컨텍스트 내에서 실행되므로 변경해야합니다. 복구하다.

    수 :

    @Before 메서드를 게시 할 수 있습니까? 그냥 테이블을 지우거나 실제로 테이블을 삭제하고 다시 만들면 궁금합니다.

  7. ==============================

    7.AbstractJUnit4SpringContextTests 및 TransactionalTestExecutionListener에 대한 Javadocs 및 소스 코드를 살펴보면 트랜잭션 처리를 원하는 테스트 메소드에 @Transactional을 추가해야합니다.

    AbstractJUnit4SpringContextTests 및 TransactionalTestExecutionListener에 대한 Javadocs 및 소스 코드를 살펴보면 트랜잭션 처리를 원하는 테스트 메소드에 @Transactional을 추가해야합니다.

    또한 @BeforeTransaction 및 @AfterTransaction 주석이있어 트랜잭션에서 실행되는 내용을보다 잘 제어 할 수 있습니다.

    @Before를 포함하여 이러한 모든 주석으로 주석 된 메소드를 작성한 다음이 메소드에서 중단 점을 사용하여 테스트를 실행하는 것이 좋습니다. 그렇게하면 스택을보고 스프링이 트랜잭션을 시작했는지 여부를 확인할 수 있습니다. 스택에 "TransactionInterceptor"와 같은 것이 있거나 이름에 "Transaction"이있는 항목이 있으면 거래를하고있는 것입니다.

  8. ==============================

    8.tx 내에있는 @Before 메소드에서 super.deleteFromTables을 수행하고 있습니다. 따라서 tx가 롤백되면 삭제도 롤백되지 않습니다.

    tx 내에있는 @Before 메소드에서 super.deleteFromTables을 수행하고 있습니다. 따라서 tx가 롤백되면 삭제도 롤백되지 않습니다.

  9. from https://stackoverflow.com/questions/971483/spring-transaction-management-test by cc-by-sa and MIT license