본문 바로가기
Spring/jpa

@DataJpaTest 정리

by 무대포 개발자 2021. 12. 15.
728x90
반응형

source 는 Github 에 있습니다.

@DataJpaTest 란?

  • Jpa Test 에 포커싱이 맞춰진 테스트 annotation 입니다.
  • 주로 Jpa test 를 할 때, 사용하며 Junit4 를 사용하면 @RunWith(SpringRunner.class) 와 같이 사용해야 합니다.
    • 같이 사용해야하는 이유는 Spring 공식 문서에 같이 써야한다고 나와있습니다.
  • DataJpaTest 는 인메모리 데이터베이스 (기본 H2) 로 설정하며, @Entity 가 붙은 클래스, Spring Data Jpa Repository 를 스캔합니다. Transactional 하며, 테스트가 종료 시 Rollback 기능도 있습니다.

@RunWith(SpringRunner.class)

  • 테스트 클래스에 RunWith 를 선언하면 JUnitFramework 에서 SpringRunner 를 호출합니다.
  • SpringRunner 클래스는 Test 를 어떻게 동작시킬지에 대한 구현체입니다. (org.junit.runner.Runner)
  • 동작 방식을 보면 실제로 테스트 클래스는 SpringRunner 에게 전달하고 SpringRunner 에서 실행합니다.
  • SpringRunner 가 하는 역할은 Spring Container 를 시작하는 작업을 수행합니다. (비용이 큽니다.)
    • 컴포넌트 주입, 설정 데이터 주입 등

@RunWith(SpringRunner.class) vs @SpringBootTest

  • RunWith 는 @Autowired, @MockBean 에 해당되는 것들만 applicationContext 에 로딩하며, SpringBootTest 는 모든 Bean 들을 applicationContext 에 로딩합니다.
  • 즉, SpringBootTest 가 비용이 더 큽니다.

Source


@RunWith(SpringRunner.class)
@DataJpaTest
public class NoGenerativeStrategyRepositoryTest {

    @Autowired
    private NoGenerativeStrategyRepository noGenerativeStrategyRepository;

    /**
     * select 한 번 한 후 조회 함.
     * @throws Exception
     */
    @Test
    public void ID생성전략이_없으며_애플리케이션에서생성한경우_SAVE_테스트() throws Exception {
        // given
        NoGenerativeStrategy noGenerativeStrategy =
                NoGenerativeStrategy.builder()
                        .id(2L)
                        .name("test")
                        .build();

        // when
        noGenerativeStrategyRepository.save(noGenerativeStrategy);
        Optional<NoGenerativeStrategy> result = noGenerativeStrategyRepository.findById(2L);

        // then
        Assert.assertThat(result.get().getName(), is("test"));
    }

    /**
     * 생성전략이 없으니 select 한 후, insert 함. 즉, 오래 걸림.
     * @throws Exception
     */
    @Test
    public void ID생성전략이_없으며_대량SAVE_테스트() throws Exception {
        List<NoGenerativeStrategy> list = new ArrayList<>();
        for (int i = 0 ; i < 1000 ; i++) {
            NoGenerativeStrategy noGenerativeStrategy =
                    NoGenerativeStrategy.builder()
                            .id(Long.valueOf(i + 1))
                            .name("test").build();
            list.add(noGenerativeStrategy);
        }
        noGenerativeStrategyRepository.saveAll(list);
    }
}

결론

  • Jpa Repository 만 테스트 해야 하는 경우가 있습니다. 그럴 경우 @DataJpaTest, RunWith 사용해서 Repository 를 테스트 하면 됩니다.

Reference

댓글