
안녕하세요!! nemo입니다!! 🐢
요즘 날씨가 진짜 후덥지근하네요
이런 날씨에 프로젝트를 하다 보니 집중력이 조금 떨어지지만… 그래도 꾸준히 나아가고 있습니다
이번 주도 하나씩 경험을 쌓아가면서 개발자로서 한 발 더 나아가는 시간을 보내고 있어요
그럼 오늘도 열심히 달려보겠습니다!!

지난번에는 예외 상황을 테스트 코드로 검증하는 방법을 정리했었는데요
이번에는 서비스 테스트에서 repository에 저장된 데이터가 다른 테스트에 영향을 주는 문제를 다뤄보려고 합니다
테스트를 작성하다 보면
첫 번째 테스트에서 저장한 데이터가 그대로 DB에 남아
두 번째 테스트의 결과가 꼬이는
이런 상황을 한 번쯤은 겪게 될텐데
(그게 나야~ 뚜바 뚜밥 뚜비두밥)
테스트는 독립적으로 실행돼야 의미가 있는데 데이터가 섞이면 신뢰성이 깨지죠
그래서 오늘은 Spring Boot 환경에서 이 문제를 어떻게 해결할 수 있는지 정리해보겠습니다
테스트 메서드마다 트랜잭션을 걸고 실행이 끝나면 자동으로 롤백되는 방식입니다
@SpringBootTest
@Transactional
class AchievementServiceTest {
@Autowired
private AchievementRepository achievementRepository;
@Test
void saveAchievement() {
achievementRepository.save(new Achievement("첫 글 작성"));
assertEquals(1, achievementRepository.count());
}
}
테스트가 끝나면 롤백 → DB가 깨끗하게 유지됩니다
👉 가장 간단하면서도 많이 쓰이는 방식이에요
단, 정말 DB에 데이터를 남기고 싶다면 @Commit을 붙여야 합니다
테스트 실행 후 Spring 컨텍스트 자체를 리셋하는 방법도 있습니다
@SpringBootTest
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
class AchievementServiceTest { ... }
👉 완전히 새로운 환경에서 테스트할 수 있지만
매번 컨텍스트를 새로 로딩해야 해서 속도가 조금 느려질 수 있습니다
테스트 실행 전후로 직접 데이터를 지워주는 방법입니다
@BeforeEach
void cleanUp() {
achievementRepository.deleteAll();
}
👉 특정 Repository만 초기화하고 싶을 때는 이 방법이 간단합니다
다만, 코드 중복이 생기기 쉽고 관리가 번거로울 수 있습니다
운영 DB와는 별도로 테스트 전용 DB를 두는 방법입니다
보통은 H2 같은 In-Memory DB를 많이 씁니다
application-test.yml
spring:
datasource:
url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
driver-class-name: org.h2.Driver
username: sa
password:
👉 @ActiveProfiles("test")를 붙여서 실행하면
운영 DB와 완전히 격리된 환경에서 테스트가 가능해집니다
테스트 독립성을 보장하는 방법에는 여러 가지가 있지만
빠르고 간단한 방법은 @Transactional 롤백
완전히 깨끗한 환경이 필요하다면 @DirtiesContext
특정 데이터만 초기화하려면 deleteAll()
운영 DB와 격리하고 싶다면 H2 같은 테스트 전용 DB
이번 프로젝트에서는 deleteAll() 방식을 쓰려고 합니다
가장 많이 쓰이는 방식은 @Transactional이라고 하네요
테스트를 작성하다 보면 "정상 작동"을 확인하는 것도 중요하지만
테스트 간의 독립성을 지키는 게 그만큼이나 중요한 것 같습니다
DB가 오염되면 원인 파악이 힘들어지고 테스트 신뢰성이 크게 떨어진다고 합니다
긴 글 읽어주셔서 감사합니다!! 🐢