Java

spring 테스트 코드 작성

blackbearwow 2025. 3. 11. 23:32

에러나 버그나 났을 때, 

팀 프로젝트에서 내가 작성한 기능이 오류가 있는 것인지 동료의 코드가 오류가 있는 것인지

프로젝트가 커지면서 기능이 이것저것 엮여있는 경우 버그가 나면 어느 기능이 오류가 나는지 

알기 위해서는 테스트 코드를 잘 작성 해놓아야 한다.

 

 

테스트는 해당 기능의 패키지에서 main과 test만 바뀐 같은 위치에서 테스트한다. 해당 클래스이름 + Test로 클래스 이름을 만드는 것이 국룰이다. intellij 에서 Ctrl + Shift + T 단축키로 테스트 클래스를 만들 수 있다.

 

메소드에 @Test를 붙여 테스트를 한다.

메소드에 @BeforeEach를 붙이면 테스트 실행전 실행되는 메소드가 된다.

메소드에 @AfterEach를 붙이면 테스트실행후 실행되는 메소드가 된다.

클래스에 @SpringBootTest를 붙이면 스프링 컨테이너에 빈이 등록된 상태에서 테스트가 진행된다.

테스트에 @Transactional을 붙이면 데이터베이스 트랜잭션 단위를 의미한다. 그리고 repository에 붙는 어노테이션과 달리 rollback을 한다. 적용하고싶다면 @Commit을 붙여야 한다.

 

junit과 assertj의 기능들을 사용해 테스트를 한다.

 

기능
assertThat(a).isEqualTo(b) a와 b가 같은지 (같은 값을 가지는지)
assertThat(a).isNotEqualTo(b) a와 b가 다른지 (같은 값을 가지는지)
assertThat(a).isSameAs(b) a와 b가 같은지 (같은 주소를 가르키는지)
assertThat(a).isNotSameAs(b) a와 b가 다른지 (같은 주소를 가르키는지)
assertThat(a).isInstanceOf(b) a가 b의 인스턴스인지
assertThat(a).isNotInstanceOf(b) a가 b의 인스턴스인가 아닌지
assertThat(a).contains(b, c) a가 b,c를 포함하는지
assertThat(a).containsExactly(b, c) a가 b,c를 포함하는지 (순서대로, 딱 지정한 것만 들어있는지)
assertThrows(a,b) b(람다 함수)를 실행시 a 오류가 던져지는지

 

테스트는

// given 테스트 실행 준비

// when 테스트 진행중

// then 테스트 결과 검증

위의 순서대로 진행된다.

 

위 테스트를 만들기 귀찮다면, intellij에서 사용자 단축키를 만들자.

파일 - 설정 - 라이브 템플릿에 custom이라는 템플릿 그룹을 만들고 custom에 라이브 템플릿 만들기를 한다.

약어는 tdd, 템플릿 텍스트에는

@Test
public void $NAME$() {
    // given
    $END$
    // when
    
    // then
}

라고 적는다. 그리고 정의에서 Java를 선택하고 확인.

 

Repository 테스트

 

테스트는 빠른 피드백을 요구하기 때문에 repository만 테스트할 경우 @SpringBootTest를 하는것은 적절하지 않다. @SpringBootTest는 애플리케이션 전체 컴포넌트를 컴포넌트 스캔하기 때문.

@DataJpaTest를 사용하면 된다. @DataJpaTest는 jpa관련 컴포넌트(EntityManager등)만 로드한다.

추가적으로 필요한 컴포넌트는 클래스 단위로 @Import({})로 가져오면 된다. 예) @Import({MemberRepository.class, CategoryRepository.class})

패키지 단위로 필요한 컴포넌트는 @ComponentScan(basePackages={"package/path", "package/path2"}로 컴포넌트 스캔하면 된다.

 

기본적으로 @DataJpaTest는 인메모리 h2 데이터베이스를 사용한다. 그러기 위해 build.gradle에 다음을 추가시킨다.

dependencies {
	testImplementation 'com.h2database:h2'
}

특정 db에 의존적인 테스트를 진행해야한다면, @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) 를 붙이고 application.properties에 해당 db설정을 해놓으면 된다.

 

@DataJpaTest
//@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@ComponentScan(basePackages = "uman.tunginside.repository")
class JpaMemberRepositoryTest {

    @Autowired
    private MemberRepository memberRepository;

    @Test
    void findById() {
        // given
        Member member = new Member();
        member.setFromMemberSignupForm(new MemberSignupForm("admin", "abc123", "admin"));
        memberRepository.save(member);
        // when
        Member result = memberRepository.findById(1L).get();
        // then
        Assertions.assertThat(result.getNickname()).isEqualTo("admin");
    }
}

예시

 

 

통합 테스트?

 

ㅁㄴㅇㄹ

'Java' 카테고리의 다른 글

spring 검증(validation, bean validation)  (0) 2025.04.11
spring 로그인 세션과 인터셉터  (0) 2025.04.03
spring 기본 개념  (0) 2025.03.11
thymeleaf 템플릿 엔진  (0) 2025.02.11
spring Controller  (0) 2025.02.08