Spring/Spring Test

[Spring][Test] 2. Integration Testing

noahkim_ 2025. 4. 21. 02:11

1. spring-test 모듈

  • 외부 시스템과 연결하지 않고도 통합테스트를 하도록 지원함
  • 다양한 테스트 프레임워크와 연동됨 (JUnit, TestNG 등)

 

2. 테스트 클래스에 의존성 주입

TestContext

  • 테스트 실행 중의 상태와 메타데이터를 캡슐화한 객체입니다.
  • 전체 테스트 컨텍스트의 흐름을 관리
기능 설명
🔁 ApplicationContext 관리
테스트 시 사용할 스프링 컨텍스트(ApplicationContext)를 생성하고, 재사용을 위해 캐싱함
💉 의존성 주입 지원
@Autowired, @Value, @MockBean 등을 통해 테스트 클래스에도 빈 주입 가능
🔄 트랜잭션 관리
@Transactional을 테스트에 적용해 자동 롤백 같은 트랜잭션 기능 제공
🔧 테스트 라이프사이클 관리
@BeforeEach, @AfterEach, @BeforeAll, @AfterAll 등의 실행 타이밍을 조절함
🧪 테스트 컨텍스트 정보 제공
테스트 클래스, 메서드, 어노테이션 등 다양한 테스트 메타데이터를 제공함

 

흐름

 

  1. @ExtendWith(SpringExtension.class)로 테스트 시작
  2. Spring이 내부적으로 TestContext 객체 생성
  3. @ContextConfiguration 또는 @SpringBootTest로 ApplicationContext 로딩
  4. TestContext가 ApplicationContext를 캐싱
  5. 테스트 클래스에 DI 수행 (@Autowired, etc.)
  6. 테스트 메서드 실행

 

 

관련 클래스

클래스 설명
TestContext
테스트에 대한 상태 정보를 담고 있음
TestContextManager
테스트 실행 시 TestContext를 관리하는 실제 매니저
SpringExtension
JUnit 5에서 TestContextManager를 사용하는 Extension

 

 

3. 컨텍스트 관리 및 캐싱

  • 테스트 클래스간 ApplicationContext를 재사용하여 사용
어노테이션 설명 비고
@ExtendWith(SpringExtension.class) JUnit 5에서 Spring TestContext Framework 연동 JUnit5에서는 필수
(JUnit4의 @RunWith 대체)
@ContextConfiguration(...) 테스트 시 로딩할 Spring Bean 설정 지정
(@Configuration or XML)
classes, locations 등으로 지정 

 

예제

더보기
@Configuration
public class AppConfig {

    @Bean
    public HelloService helloService() {
        return new HelloService();
    }
}
public class HelloService {
    public String sayHello() {
        return "hello spring test!";
    }
}
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = AppConfig.class)
public class HelloServiceTest1 {

    @Autowired
    private ApplicationContext context;

    @Autowired
    private HelloService helloService;

    @Test
    void testHelloService1() {
        System.out.println("HelloServiceTest1의 context: " + context);

        assertEquals("hello spring test!", helloService.sayHello());
    }
}
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = AppConfig.class)
public class HelloServiceTest2 {

    @Autowired
    private ApplicationContext context;

    @Autowired
    private HelloService helloService;

    @Test
    void testHelloService2() {
        System.out.println("HelloServiceTest2의 context: " + context);

        assertEquals("hello spring test!", helloService.sayHello());
    }
}
HelloServiceTest1의 context: org.springframework.context.support.GenericApplicationContext@6ed3f258, started on Mon Apr 21 01:29:33 KST 2025
HelloServiceTest2의 context: org.springframework.context.support.GenericApplicationContext@6ed3f258, started on Mon Apr 21 01:29:33 KST 2025

 

4. 트랜잭션 관리

 

  • 테스트 격리: 각 테스트별 자동 롤백을 수행하므로 독립적으로 실행되며, 이전 테스트의 DB 상태가 영향을 미치지 않음.
  • @Commit 사용: 특정 테스트에 대해서는 DB 변경을 실제로 반영할 수 있음.

 

예제

더보기
@SpringJUnitConfig(DatabaseConfig.class)
public class MemberRepositoryTest {

    @Autowired
    private MemberRepository memberRepository;

    @Test
    @Transactional
    void testCreateMember() {
        memberRepository.save("noah");
        Member member = memberRepository.findUserByUsername("noah");

        assertEquals("noah", member.getUsername());
    }
}

 

테스트 결과를 db에 반영하기

@SpringJUnitConfig(DatabaseConfig.class)
public class MemberRepositoryTest {

    @Autowired
    private MemberRepository memberRepository;

    @Test
    @Transactional
    @Commit
    void testCreateMember() {
        memberRepository.save("noah");
        Member member = memberRepository.findUserByUsername("noah");

        assertEquals("noah", member.getUsername());
    }
}

 

 

5. 지원 클래스

Spring은 통합 테스트를 쉽게 작성할 수 있도록 도와주는 추상 클래스들을 제공합니다.

항목 설명
ApplicationContext 접근
테스트 내에서 Bean을 가져와 직접 사용하거나 검증할 수 있습니다.
JdbcTemplate 사용
SQL을 직접 실행해서 DB 상태를 확인하거나 테스트 전후 검증에 사용할 수 있습니다.
공통 추상 클래스 작성
여러 테스트에서 공통적으로 필요한 설정, 유틸을 포함한 AbstractIntegrationTest와 같은 클래스를 만들어 상속하면 좋습니다.

 

 

출처

 

'Spring > Spring Test' 카테고리의 다른 글

[Spring][Test] 3. Testing Annotations  (1) 2025.04.21
[Spring][Test] 1. Unit Testing  (2) 2025.04.19