Database 선정
- 일반적으로 테스트 시에는 main 서버에서 사용하는 db를 사용하지 않고 임베디드 h2 디비를 사용한다.
- h2 데이터베이스는 자바로 개발되어 있고, JVM 안에서 메모리 모드로 동작하는 특별한 기능을 제공한다. 따라서 임베디드 모드로 h2 디비를 사용할 수 있는 것이다.
- 또한, 인 메모리 기반이기에 속도가 빠르다.

- 임베디드 h2 디비를 직접 사용하고자 할 때는 위와 같이 DataSource를 빈으로 등록해주면 된다.
- jdbc:h2:mem 부분이 제일 중요한 부분으로 임베디드 모드로 h2를 사용하겠다는 것이다.
- "DB_CLOSE_DELAY=-1"은 JVM이 동작하는 동안 모든 데이터베이스 연결이 끊어져도 데이터베이스를 종료(초기화)하지 않는다는 의미이다.
-> 만약 일시적으로 데이터베이스 연결이 모두 끊기면 테이블, 데이터 등 모든 게 다 초기화된다.
- 스프링 부트는 자동으로 임베디드 h2 디비를 사용하도록 자동 구성을 해준다. 따라서 위와 같이 직접 설정해줄 필요가 없다.
- 주의할 점으로는 매번 h2 디비가 새롭게 뜨는 거기 때문에, 스키마를 정의해줘야 한다.
- test/resources 밑에 schema.sql 파일을 만들어서 이 파일안에 스키마를 정의해주면 된다.
- 파일명은 꼭 지켜줘야 하며, 스프링 부트가 이 파일을 찾아서 임베디드 h2 디비에 실행해준다.
- cf) main/resources 밑에 만들면 main 환경에서도 똑같이 동작한다.
- 이 때 실제 db를 사용하고자 한다면 @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)으로 설정하면 된다.
test 설정 파일
- main 서버와 다른 데이터베이스를 사용해야 하므로 properties에서 설정 변경은 필수적이다.
- 기본적으로 main 폴더에 있는 application.yml은 로드가 되지만 active profile을 설정하면 다른 yml을 로드할 수 있다.
- 이 때 profile로 로드된 yml이 기존에 로드된 yml을 덮어씌운다.
- application-'profile'.properties와 같이 profile 부분이 같은 설정 파일을 로드한다.
- 만약 test 폴더 내부에 resources 내부에 application.properties를 만들면 main이 아닌 test에 있는 설정 파일만을 로드한다.
jpa를 사용할 시에 repository를 테스트할 필요없다. 하지만 @Query를 이용하거나 QueryDSL을 이용할 때는 테스트를 해야 한다.
org.springframework.transaction.annotation.Transactional의 @Transactional을 붙이면 해당 테스트 메소드가 끝나면 자동으로 Rollback 처리를 해준다.
이 어노테이션이 테스트 메소드 위에 있어야 자동 Rollback 처리를 해준다. 즉, 이 어노테이션이 테스트 메소드에 없고 호출한 메소드에 이 어노테이션이 있는 경우엔 롤백이 되지 않는다.
테스트 db 데이터 입력
- JDBCTemplate를 주입 받아 데이터를 넣을 수 있다. 이를 위해 @BeforeEach를 사용하자. -> properties에 속성값으로 설정해 @Value로 가져오는 방법을 사용하는게 더욱 깔끔하다.
- @Sql("file.sql")로 테스트별로 적용할 데이터를 설정할 수 있다. @BeforeEach 다음에 @Sql이 실행된다. -> 이 방법을 사용하는게 더 깔끔하고 좋을 거 같다.
@SpringBootTest
@TestPropertySource("/application-test.properties")
public class StudentAndGradeServiceTest {
@Value("${info.school.name}")
private String schoolName;
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
private StudentAndGradeService studentService;
@Autowired
private StudentDao studentDao;
@BeforeEach
void setUpDatabase() {
jdbcTemplate.execute("insert into student(id, firstname, lastname, email_address) "
+ "values(1,'Eric','Roby','asdasd@asdasd')");
}
@AfterEach
void setupAfterTransaction() {
jdbcTemplate.execute("delete from student");
}
@Test
void createStudentService() {
studentService.createStudent("Choi", "Jaeh", "mail@gmail.com");
CollegeStudent student = studentDao.findByEmailAddress("mail@gmail.com");
assertEquals("mail@gmail.com", student.getEmailAddress(), "find by email");
}
@Test
void isStudentNullCheck() {
assertTrue(studentService.checkIfStudentIsNull(1));
assertFalse(studentService.checkIfStudentIsNull(0));
}
@Test
void deleteStudentService() {
Optional<CollegeStudent> deletedCollegeStudent = studentDao.findById(1);
assertTrue(deletedCollegeStudent.isPresent());
studentDao.findByEmailAddress(deletedCollegeStudent.get().getEmailAddress());
studentService.deleteStudent(1);
deletedCollegeStudent = studentDao.findById(1);
assertFalse(deletedCollegeStudent.isPresent());
}
@Test
@Sql("/insertData.sql")
void getGradeBookService() {
Iterable<CollegeStudent> iterableCollegeStudent = studentService.getGradeBook();
List<CollegeStudent> collegeStudents = new ArrayList<>();
System.out.println(schoolName);
for (CollegeStudent collegeStudent : iterableCollegeStudent) {
collegeStudents.add(collegeStudent);
}
assertEquals(2, collegeStudents.size());
}
}
'Spring Boot > testing' 카테고리의 다른 글
| JUnit 5 테스트 인스턴스 생명주기 (0) | 2025.06.05 |
|---|---|
| 서비스단 통합 테스트 회고 및 작성법 (0) | 2025.03.13 |
| 비동기 테스트 주의 사항 (0) | 2025.02.01 |
| 테스트 픽스처(Test Fixture) (0) | 2025.02.01 |
| 통합 테스트 @SpringBootTest vs @DataJpaTest (0) | 2025.02.01 |