복붙노트

[SPRING] JUnit에서 Spring을 사용하여 서비스를 테스트 할 때 데이터베이스 트랜잭션을 롤백하는 방법은 무엇입니까?

SPRING

JUnit에서 Spring을 사용하여 서비스를 테스트 할 때 데이터베이스 트랜잭션을 롤백하는 방법은 무엇입니까?

내 DAO와 서비스를 테스트하는 데 문제가 없지만 INSERT 또는 UPDATE를 테스트 할 때 트랜잭션을 롤백하고 데이터베이스에 영향을 미치지 않습니다.

트랜잭션을 관리하기 위해 내 서비스에서 @Transactional을 사용하고 있습니다. 알고 싶습니다. 트랜잭션이 정상적으로 작동하는지 알 수 있습니까?하지만 데이터베이스를 변경하지 못하도록 롤백 할 수 있습니까?

이것은 나의 시험이다.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:/META-INF/spring.cfg.xml")
@TransactionConfiguration(defaultRollback=true)
public class MyServiceTest extends AbstractJUnit38SpringContextTests  {
    @Autowired
    private MyService myService;

    @BeforeClass
    public static void setUpClass() throws Exception {
    }

    @AfterClass
    public static void tearDownClass() throws Exception {
    }

    @Test
    public void testInsert(){
        long id = myService.addPerson( "JUNIT" );
        assertNotNull( id );
        if( id < 1 ){
            fail();
        }
    }
}

문제는 트랜잭션이 롤백 되었기 때문에이 테스트가 실패하지만 삽입이 정상적인 것입니다. @TransactionConfiguration (defaultRollback = true)을 제거하면 테스트 통과지만 새 레코드가 데이터베이스에 삽입됩니다.

@Test
@Transactional
@Rollback(true)
public void testInsert(){
    long id = myService.addPerson( "JUNIT" );
assertNotNull(id);
if( id < 1 ){
        fail();
    }
}

이제는 패스를 올바르게 테스트 할 수 있지만 롤백은 무시되고 레코드는 데이터베이스에 삽입됩니다. 나는 명백하게 @Transactional과 함께 myService 내부의 addPerson () 메소드에 주석을 달았다. 롤백이 무시되는 이유는 무엇입니까?

해결법

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

    1.트랜잭션 경계를 테스트 메소드의 경계까지 확장해야합니다. 테스트 메소드 (또는 전체 테스트 클래스)에 @Transactional이라는 주석을 달아서 할 수있다.

    트랜잭션 경계를 테스트 메소드의 경계까지 확장해야합니다. 테스트 메소드 (또는 전체 테스트 클래스)에 @Transactional이라는 주석을 달아서 할 수있다.

    @Test 
    @Transactional
    public void testInsert(){ 
        long id=myService.addPerson("JUNIT"); 
        assertNotNull(id); 
        if(id<1){ 
            fail(); 
        } 
    } 
    

    또한이 방법을 사용하여 롤백 전에 데이터가 올바르게 기록되었는지 확인할 수 있습니다.

    @Autowired SessionFactory sf;
    
    @Test 
    @Transactional
    public void testInsert(){ 
        myService.addPerson("JUNIT"); 
        sf.getCurrentSession().flush();
        sf.getCurrentSession().doWork( ... check database state ... ); 
    } 
    
  2. ==============================

    2.체크 아웃

    체크 아웃

    http://static.springsource.org/spring/docs/2.5.x/reference/testing.html

    특히 8.3.4 절

    Spring은 각 테스트를 트랜잭션에서 랩핑 할 테스팅을위한 몇 가지 클래스를 가지고 있으므로 DB는 변경되지 않는다. 원하는 경우 해당 기능을 변경할 수 있습니다.

    편집 - 더 많은 정보를 바탕으로 볼 수도 있습니다.

    AbstractTransactionalJUnit38SpringContextTests at

    http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/test/context/junit38/AbstractTransactionalJUnit38SpringContextTests.html

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

    3.수업 전 주석을 다음과 같이 사용하십시오.

    수업 전 주석을 다음과 같이 사용하십시오.

    @TransactionConfiguration(transactionManager = "txManager",defaultRollback = true)
    @Transactional
    

    여기 txManager는 응용 프로그램 컨텍스트의 트랜잭션 관리자입니다.

    여기서 txManager는 응용 프로그램 컨텍스트에서 트랜잭션 관리자의 인스턴스 또는 Bean ID입니다.

    <!-- Transaction Manager -->
        <bean id="txManager"
              class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <property name="sessionFactory" ref="sessionFactory" />
        </bean>
    
        <tx:annotation-driven transaction-manager="txManager" />
    

    setUp () 메소드 안에 코드를 추가하면 테스트 시작시 실행되고 마지막 마무리 코드는 마지막에 실행될 teatDown () 메소드에 넣어야합니다. 또는 @Before 및 @After 주석을 대신 사용할 수도 있습니다.

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

    4.귀하의

    귀하의

    myService.addPerson("JUNIT"); 
    

    메서드는 @Transactional처럼 주석을 달았습니다.이 문제를 해결하기 위해 다른 종류 또는 오류가 발생합니다. 따라서 DAO 방법을 테스트하는 것이 좋습니다.

  5. from https://stackoverflow.com/questions/4166983/how-to-rollback-a-database-transaction-when-testing-services-with-spring-in-juni by cc-by-sa and MIT license