JVM/JUnit

[JUnit] JUnit의 Rollback 수행 관리

헹창 2023. 10. 3.
반응형

@Transactional

  • method, class 단위로 설정 가능
  • 테스트 시작 전 트랜잭션을 시작, 테스트 완료 후 항상 롤백하여 다음 테스트에 영향을 주지 않는다.
class Test {

	@Test
	@Transactional
	void test1() {
		// ...
	}

	@Test
	void test2() {
		// ...
	}

}

@Rollback (false)

class 단위 @Transactional 선언한 경우, 모든 메소드에 대해 적용된다. 이 때, 특정 메소드만 rollback 처리 제외되도록 설정 가능하다

@Transactional
class Test {

	@Test
	void test1() {
		// ...
	}

	@Test
	@Rollback(false)
	void test2() {
		// ...
	}

}

 

@BeforeTransaction & @AfterTransaction

트랜잭션이 시작되기 전/종료된 후 실행되는 메소드임을 나타냄

@BeforeTransaction
void beforeTransaction() {
	// logic to be run before a transaction is started
}

@AfterTransaction 
void afterTransaction() {
    // logic to be run after a transaction has ended
}

 

@Before 과 @After의 Transaction 범위

class Test {
	@BeforeAll
	@Transactional
	void beforeAll() {
		// ...
	}

	@BeforeEach
	@Transactional
	void beforeEach() {

		// ...

	}
	@Test
	@Transactional
	void test() {
		// ...
	}

	@AfterEach
	@Transactional
	void afterEach() {
		// ...
	}

	@AfterAll
	@Transactional
	void afterAll() {
		// ...
	}

}
  • 테스트의 LifeCycle이 메소드 단위인 경우, @BeforeEach, @AfterEach 와 @Test는 같은 Transaction을 공유한다.
  • 반면, 클래스 단위의 lifecycle을 가지는 @BeforeAll, @AfterAll은 @Test와 같은 Transaction을 공유하지 않는다.

 

 

 

JUnit에서 rollback에 대한 Exception을 설정하지 않아도 rollback이 진행되는 이유?

@Transactional을 사용하면, Test 내에서 Exception을 발생 시키지 않아도 test가 완료되면 rollback이 된다.

@Rollback (Spring Test 공식 문서)

  • @Rollback 어노테이션이 있다면, Transaction이 끝나고 commit하지 않고 rollback을 시킨다. (Rollback annotation defualt : true)
  • TransactionTestExecutionListener 에는 testClass에 대해 Rollback 어노테이션과 자동적으로 결합해주는 부분이 존재한다.
    Spring에서 자동적으로 Transaction에 대해 정의되어있는 메소드나 클래스를 TransactionTestExecutionListener 에서 탐색하여 Rollback class와 결합해주기 때문에 rollback이 진행되는 것이다.
protected final boolean isDefaultRollback(TestContext testContext) throws Exception {
	Class<?> testClass = testContext.getTestClass();
	Rollback rollback = TestContextAnnotationUtils.findMergedAnnotation(testClass, Rollback.class);
	boolean rollbackPresent = (rollback != null);

	if(rollbackPresent) {
		boolean defaultRollback = rollback.value();
		if(logger.isDebugEnabled()) {
			logger.debug(String.format("Retrieved default @Rollback(%s) for test class [%s].",
					defaultRollback, testClass.getName()));
		}
		return defaultRollback;
	}

	return true;
}
728x90
반응형

댓글

추천 글