TDD 개발 주기
- Red : 작은 단위(Class 등)의 실패하는 테스트 코드 작성
- Green : 테스트 코드를 성공시키기 위한 실제 코드 작성
- Yellow : 중복 코드 제거, 일반화 등 리팩토링 수행
IntelliJ(IDE), Spring Boot 2.7.6, Java17 환경에서 JUnit5를 사용한 예제 테스트 코드를 작성해보겠습니다.
사진과 같이 src 디렉토리 하위에 test 디렉토리를 생성하고, root로 사용할 디렉토리가 초록색이 되어야 합니다. IntelliJ의 Spring Initializr으로 프로젝트 생성 시 test 디렉토리 생성 및 설정을 따로 하지 않아도 사진과 같이 설정이 완료되어 있었습니다.
또한 위와 같이 org.projectlombok:lombok
과 org.springframework.boot:spring-boot-starter-test
의존성을 추가해야 합니다.
테스트를 작성하고자 하는 Class의 이름 부분에 마우스를 놓고 Alt+Enter을 누르면 위와 같이 Create Test 창이 뜹니다. OK를 누르면 위에서 설정한 test의 root 디렉토리에 DemoTest Class가 생성되고, 해당 Class 내에 테스트 코드를 작성하면 됩니다.
@Test : 해당 method가 test method임을 명시
@BeforeEach : 각 테스트 시작 전 실행
@AfterEach : 각 테스트 종료 후 실행
@BeforeAll : 전체 테스트 시작 전 실행 (Static 처리 필요)
@AfterAll : 전체 테스트 종료 후 실행 (Static 처리 필요)
@SpringBootTest : @SpringBootApplication에 접근 -> Application 하위의 모든 Bean 스캔 및 로드 -> Test Application Context 생성 후 Bean 추가, MockBean이 존재하는 경우 교체
@ExtendWith : JUnit4의 @RunWith이 변경된 것으로, 메인으로 실행될 Class 지정에 사용
@WebMvcTest : @WebMvcTest(ClassName.class) 형태, () 안에 명시된 Class만 로드하여 테스트 수행, Controller 관련 코드만 테스트할 경우 사용
@MockBean : 테스트 할 Class에서 주입받고 있는 객체에 대해 실제 행위를 하지 않는 가짜 객체 생성, given() method에서 동작 정의
@AutoConfigureMockMvc : spring.test.mockmvc의 설정을 로드하면서 MockMvc의 의존성을 자동으로 주입, RESTful API 테스트 시 사용
@Import : 필요한 Class들을 Configuration으로 만들어 사용
입력된 문자열을 대문자로 변경하는 간단한 코드에 대해 테스트 코드를 작성해보겠습니다.
package com.example.study;
import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
class DemoTest {
static List<String> words = new ArrayList<>();
@Autowired
Demo demo = new Demo();
@BeforeAll
static void beforeAll(){
System.out.println("Initial Size: " + words.size());
}
@AfterAll
static void afterAll(){
System.out.println(words);
}
@BeforeEach
void beforeEach(){
System.out.println("Test Started");
}
@AfterEach
void afterEach(){
System.out.println("Test Ended");
}
@Test
void toUpperCase() {
words.add("hello");
words.add("java");
words.add("spring");
words.add("boot");
List<String> answers = new ArrayList<>();
answers.add("HELLO");
answers.add("JAVA");
answers.add("SPRING");
answers.add("BOOT");
for(int i=0; i<words.size(); i++){
String test = demo.convertString(words.get(i));
String answer = answers.get(i);
assertEquals(test, answer);
if(test.equals(answer)){
words.set(i, test);
}
}
}
}
테스트 결과는 다음과 같습니다.