에러나 버그나 났을 때,
팀 프로젝트에서 내가 작성한 기능이 오류가 있는 것인지 동료의 코드가 오류가 있는 것인지
프로젝트가 커지면서 기능이 이것저것 엮여있는 경우 버그가 나면 어느 기능이 오류가 나는지
알기 위해서는 테스트 코드를 잘 작성 해놓아야 한다.
테스트는 해당 기능의 패키지에서 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 |