H2 임베디드와 Mockito: 테스트 코드에서의 활용과 차이점

coldrice99·2024년 12월 10일
0
post-thumbnail

테스트 코드는 프로젝트의 품질을 보장하는 핵심 도구입니다. 특히 데이터베이스와 연동된 코드를 테스트할 때, 테스트 환경이 실제 데이터베이스와 유사한지 여부는 매우 중요한 요소입니다. 이 글에서는 H2 임베디드 데이터베이스Mockito를 사용하는 방식의 차이를 비교하며, 왜 H2 임베디드 데이터베이스가 데이터베이스 연동 테스트에 권장되는지에 대해 다룹니다.


1️⃣ H2 임베디드 데이터베이스: 왜 사용할까?

H2 임베디드는 메모리 기반의 경량 데이터베이스로, 실제 데이터베이스와 유사한 환경을 제공합니다. 이를 통해 JPA나 JDBC와 같은 데이터 액세스 로직을 실제 데이터베이스에서 테스트하듯이 검증할 수 있습니다.

✅ 장점 1: 실제 데이터베이스와 유사한 환경

H2 임베디드는 실제 SQL 문법과 동작을 지원하므로, 실제 데이터베이스 환경과 유사한 조건에서 테스트를 실행할 수 있습니다.

@SpringBootTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.ANY)
public class UserRepositoryTest {

    @Autowired
    private UserRepository userRepository;

    @Test
    public void userSaveTest() {
        // Given
        User user = new User("test@example.com", "password");

        // When
        userRepository.save(user);

        // Then
        User result = userRepository.findByEmail("test@example.com").orElseThrow();
        assertEquals("test@example.com", result.getEmail());
    }
}

위 예제는 실제 데이터베이스를 사용하는 것처럼 JPA 레포지토리 동작을 테스트합니다.
장점:

  • 엔티티 매핑 오류, 쿼리 오류, 트랜잭션 문제 등 데이터베이스와 관련된 잠재적인 문제를 초기에 발견 가능.

✅ 장점 2: 통합 테스트 환경 제공

H2 임베디드는 단순히 데이터를 저장하는 것을 넘어, 애플리케이션과 데이터베이스 간의 연동을 포함한 통합 테스트를 가능하게 합니다.
이는 단순 로직 테스트를 넘어 애플리케이션 전체의 동작을 검증할 수 있는 강력한 도구가 됩니다.


2️⃣ Mockito를 사용하는 방식: 언제 유용할까?

Mockito는 주로 단위 테스트에서 레포지토리, 서비스, 컨트롤러의 특정 메서드를 모킹(mocking)하여 테스트하는 데 사용됩니다.

@ExtendWith(MockitoExtension.class)
public class UserServiceTest {

    @Mock
    private UserRepository userRepository;

    @InjectMocks
    private UserService userService;

    @Test
    public void findUserTest() {
        // Given
        User mockUser = new User("test@example.com", "password");
        Mockito.when(userRepository.findByEmail("test@example.com")).thenReturn(Optional.of(mockUser));

        // When
        User result = userService.findUserByEmail("test@example.com");

        // Then
        assertEquals("test@example.com", result.getEmail());
    }
}

Mockito를 사용하면 특정 레포지토리 메서드의 동작을 모킹하여, 반환값을 미리 설정하고 로직을 검증할 수 있습니다.

⛔ 문제점: 실제 데이터베이스와의 불일치

Mockito는 테스트 환경에서 실제 데이터베이스와 독립적으로 동작하므로 아래와 같은 한계가 존재합니다:

  1. 레포지토리 구현 검증 실패

    • 쿼리 작성 오류가 있어도 테스트가 성공할 수 있습니다.
    • 예를 들어, @Query로 작성한 JPQL이 실제 데이터베이스에서 실행되지 않을 경우, Mockito 테스트에서는 이를 검출하지 못합니다.
  2. 엔티티 매핑 검증 부족

    • @Column, @OneToMany 등 데이터베이스와의 매핑이 잘못되었을 때 오류를 발견할 수 없습니다.
  3. 테스트 신뢰도 저하

    • 실제 데이터베이스와의 상호작용 없이 반환값을 강제로 설정하기 때문에, 레포지토리의 동작이 실제 서비스와 일치하지 않을 가능성이 높아집니다.

3️⃣ H2 임베디드와 Mockito: 언제, 어떻게 사용할까?

H2 임베디드를 사용할 때

  • JPA, JDBC 테스트: 실제 데이터베이스와의 연동을 검증해야 하는 경우.
  • 쿼리 검증: JPQL이나 Native Query의 실행 가능성과 성능 검증이 필요한 경우.
  • 통합 테스트: 데이터베이스와의 상호작용을 포함한 전체적인 동작 검증이 필요한 경우.

Mockito를 사용할 때

  • 단위 테스트: 데이터베이스와 독립적으로 특정 메서드나 로직을 검증해야 하는 경우.
  • 테스트 속도: 빠른 테스트가 필요한 경우.
  • 의존성 분리: 데이터베이스와의 상호작용 없이 서비스나 컨트롤러 로직만 검증할 때.

4️⃣ H2 임베디드를 사용하는 이유

결론적으로, H2 임베디드는 데이터베이스와 연동된 애플리케이션의 테스트에서 테스트 신뢰도를 높이는 가장 적합한 도구입니다.
Mockito는 단위 테스트에서는 유용하지만, 실제 데이터베이스와 관련된 문제를 발견하는 데는 한계가 있습니다.

요약:

  • H2 임베디드: 데이터베이스 연동 로직, 엔티티 매핑, 쿼리 검증 등 통합 테스트에 적합.
  • Mockito: 특정 메서드나 로직을 빠르고 독립적으로 테스트할 때 적합.

테스트의 목표는 단순히 테스트 코드를 작성하는 것이 아니라, 실제로 발생할 수 있는 오류를 조기에 발견하여 프로젝트의 품질을 높이는 데 있습니다.

profile
서두르지 않으나 쉬지 않고

0개의 댓글