2012-03-26 3 views
4

저는 매우 간단한 설정 즉, 서비스에 대한 메소드를 호출하는 컨트롤러를 가지고 있습니다. 이 서비스에서는 객체를 DB에 저장하고 JMS 메시지를 주입 된 JMSTemplate을 사용하여 대기열에 보냅니다. 서비스에는 기본적으로 활성화 된 트랜잭션이 있습니다.Grails : 통합 테스트에서의 트랜잭션

ActiveMQ 서버를 수동으로 테스트 할 때 예외가 발생하고 트랜잭션이 롤백됩니다. 그물 효과도 객체가 DB에 저장되지 않습니다. 문제 없다.

그러나 내가 컨트롤러를 호출 한 후 카운트 쿼리를 사용하여 개체가 DB에 저장되지 않았는지 확인하기 위해 ACERT (ActiveMQ 사용)를 통해이 작업을 실행하면 어설 션이 실행됩니다. 카운트가 1이라고 말하지 않습니다. 테스트 시작시 테스트가 시작될 때 테스트가 시작될 때 DB에 이러한 개체가 없음을 확인했습니다.

예상되는 동작 (어쩌면 통합 테스트 환경에서 트랜잭션의 특성으로 인해) 또는 잠재적으로 뭔가 잘못되어 있습니까? JMS 서버가 다운되어 RuntimeException이기 때문에 여전히 예외가 발생합니다.

Grails integration tests and transactions이 예상되는 인상을줍니다. 통합 테스트에서 트랜잭션 동작을 테스트하는 방법에 대한 모범 사례에 대한 제안이 있습니까?

+0

정확하게 기억하면 테스트가 완료 될 때까지 트랜잭션이 롤백되지 않습니다. 따라서 트랜잭션이 아직 롤백되지 않았기 때문에 어설 션을 수행 할 때 데이터가 db에 저장 된 것처럼 보입니다. – GreyBeardedGeek

+0

예, 테스트와 컨트롤러 모두에서 동일한 트랜잭션이 사용 된 것 같습니다. 이와 같은 경우에 사용할 표준 패러다임이 있는지 궁금합니다. 필자는 새로운 트랜잭션이 필요하도록 테스트하기 위해 컨트롤러 코드를 변경하고 싶지 않습니다. – Rama

+1

이 블로그 게시물 - http://www.fepede.net/blog/?p=27은 컨트롤러와 서비스가 테스트 트랜잭션을 사용하지 않고 자체 트랜잭션을 수행하게하는 테스트를 비 트랜잭션으로 만드는 방법을 보여줍니다. . 단점은 예외가 발생하지 않으면 트랜잭션이 커밋되고 정리해야한다는 것입니다. – GreyBeardedGeek

답변

7

의견이 답변에 노출 될 때 모든 사람이 대답하는 대신 댓글을 쓰는 이유를 잘 모릅니다. 나는 안으로 뛰어 들어가고 답답한 점을 방해하려고 노력할 것이다!

그렇습니다. Spock 테스트에서는 whens, thens, givens 등 전체 테스트에서 동일한 트랜잭션이 모두 실행됩니다. 따라서 테스트가 끝날 때까지는 원하는 롤백을 볼 수 없습니다.

테스트 클래스의 맨 위에 "static transactional = false"를 추가하여 테스트를 비 트랜잭션으로 설정할 수 있습니다. 물론 낙진은 테스트가 실행 된 후에 데이터베이스를 정리해야합니다 (데이터베이스 위생이 중요한 경우). 하나의 큰 문제는 Grails IntegrationSpec 클래스에 트랜잭션이 false로 설정 될 때마다 폭발하는 버그가 있다는 것입니다.

Grails 2.3 IntegrationSpec cannot be transactional false 기본적으로

, 자신의 클래스로 grails.test.spock.IntegrationSpec의 모든 코드를 복사의 트랜잭션 성격을 존중 버전의 몇 가지 방법을 바꾸기 : 그래서 그 문제에 대한 해결책을 가지고 시험.

관련 문제