- given: 테스트 실행을 준비하는 단계
- when: 테스트를 진행하는 단계
- then: 테스트 결과를 검증하는 단계
1) JUnit: 자바 프로그래밍 언어용 단위 테스트 프레임워크
2) Spring Test & Sprint Boot Test: 스프링 부트 애플리케이션을 위한 통합 테스트 지원
3) AssertJ: 검증문인 어설션을 작성하는 데 사용되는 라이브러리
4) Hamcrest: 표현식을 이해하기 쉽게 만드는 데 사용되는 Matcher 라이브러리
5) Mockito: 테스트에 사용할 가짜 객체인 목 객체를 쉽게 만들고, 관리하고, 검증할 수 있게 지원하는 테스트 프레임워크
6) JSONassert: JSON용 어설션 라이브러리
7) JsonPath: JSON 데이터에서 특정 데이터를 선택하고 검색하기 위한 라이브러리
이 중 JUnit과 AssertJ를 가장 많이 사용한다.
JUnit은 자바를 위한 단위 테스트 프레임워크이다.
- 단위 테스트: 작성한 코드가 의도대로 작동하는지 작은 단위(메소드)로 검증하는 것
1) 테스트 방식을 구분할 수 있는 어노테이션을 제공
2) @Test 어노테이션으로 메소드를 호출할 때 마다 새로운 객체를 생성(독립 테스트 가능)
3) 예상 결과를 검증하는 assert메소드 제공
4) 사용방법이 단순, 즉각적인 피드백 제공
test/java에 JUnitTest.java 생성
public class JUnitTest{
@DisplayName("1 + 2는 3이다")
@Test
public void junitTest(){
int a = 1;
int b = 2;
int sum = 3;
Assertions.assertEquals(sum, a+b);
}
}
1) @DisplayName: 테스트 이름을 명시
2) @Test: 테스트를 수행하는 메소드라는 것을 명시, 테스트 할때마다 객체만들고 테스트 끝나면 객체를 삭제함.
public class JUnitCycleTest{
@BeforeAll
static void beforeAll(){
System.out.println("@BeforeAll");
}
@BeforeEach
public void beforeEach(){
System.out.println("@BeforeEach");
}
@Test
static void test1(){
System.out.println("test1");
}
@Test
static void test2(){
System.out.println("test2");
}
@Test
static void test3(){
System.out.println("test3");
}
@AfterAll
static void afterAll(){
System.out.println("@AfterAll");
}
@AfterEach
public void afterEach(){
System.out.println("@AfterEach");
}
}
1) @BeforeAll: 전체 테스트를 시작하기 전에 처음으로 한 번만 실행함.
ex> DB를 연결할 때, 테스트 환경을 초기화할 때
2) @BeforeEach: 테스트케이스를 실행하기 전에 매번 실행한다.
ex> 테스트 메소드에서 사용하는 객체를 초기화, 테스트에 필요한 값을 미리 넣어 사용
3) @AfterAll: 전체 테스트를 마치고 종료하기 전에 한 번만 실행함.
ex> DB연결을 종료할 때, 공통적으로 사용하는 자원을 해제할때
4) @AfterEach: 각 테스트 케이스를 종료하기 전 매번실행
ex> 테스트 이후 특정 데이터를 삭제할 때
테스트 메소드 객체가 생성하기 전에 한번만 호출 -> static
테스트 메소드 객체가 실행될때 마다 호출 -> 그냥 public
검증문의 가독성을 높여주는 라이브러리이다.
Assertions.assertEquals(sum, a+b);
위 코드는 명확하지 않아 가독성이 좋지 않다.
assertThat(a+b).isEqualTo(sum);
AssertJ를 통해 좋은 가독성을 가질 수 있다.
| 메소드 이름 | 설명 |
|---|---|
| isEqualTo(A) | A값과 같은지 검증 |
| isNotEqualTo(A) | A값과 다른지 검증 |
| contains(A) | A값을 포함하는지 검증 |
| doesNotContain(A) | A값을 포함하지 않는지 검증 |
| startsWith(A) | 접두사가 A인지 검증 |
| endsWith(A) | 접미사가 A인지 검증 |
| isEmpty() | 비어있는지 검증 |
| isNotEmpty() | 비어있지 않은지 검증 |
| isPositive() | 양수인지 검증 |
| isNegative() | 음수인지 검증 |
| isGreaterThan(1) | 1보다 큰값인지 검증 |
| isLessThan(1) | 1보다 작은값인지 검증 |
| isNotNull() | NULL이 아닌지 검증 |
| isZero() | 0인지 검증 |
컨트롤러 클래스에
Alt+Enter를 눌러 CREATE TEST를 한다.
@SpringBootTest
@AutoConfigureMockMvc
class TestControllerTest{
@Autowired
protected MockMvc mockMvc;
@Autowired
private WebApplicationContext context;
@Autowired
private MemberRepository memberRepository
@BeforeEach
public void mockMvcSetUp(){
this.mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
}
@AfterEach
public void cleanUp(){
memberRepository.deleteAll();
}
}
1) @SpringBootTest: 이 어노테이션은 스프링 부트 애플리케이션의 전체 컨텍스트를 로드하여 통합 테스트를 수행하도록 설정한다. 이를 통해 실제 애플리케이션과 동일한 환경에서 테스트를 수행할 수 있다.
2) @AutoConfigureMockMvc: MockMvc를 생성하고 자동으로 구성한다.
MockMvc는 애플리케이션을 서버에 배포하지 않고도 테스트용 MVC환경을 만들어 요청, 전송, 응답 기능을 제공하는 유틸리티 클래스이다.(컨트롤러를 테스트할때 사용함)
3) @BeforeEach: 각 테스트 메소드 실행전에 MockMvc를 설정해준다.
4) @AfterEach: 각 테스트 메소드 종료전에 테이블에 있는 데이터를 모두 삭제한다.
@DisplayName("getAllMembers: 아티클 조회에 성공한다.")
@Test
public void getAllMembers() throws Exception{
//given
final String url = "/test";
Member savedMember = memberRepository.save(new Member(1L, "홍길동"));
//when
final ResultActions result = mockMvc.perform(get(url)
.accept(MediaType.APPLICATION_JSON));
//then
result
.andExpect(status().isOk())
.andExpect(jsonPath("$[0].id").value(savedMember.getId()))
.andExpect(jsonPath("$[0].name").value(savedMember.getName()));
}
1) perform(): 요청을 전송하는 역할을 하는 메소드이다.
2) accept(): HTTP 요청 헤더에 Accept 헤더를 추가하여, 서버에게 응답을 어떤 형식으로 받아야 하는지 명시한다.(MediaType.APPLICATION_JSON은 서버가 JSON 형식으로 응답할 것을 기대한다는 것을 나타냄)
3) ResultActions 객체: 요청의 결과를 받는다. ReusltActions 객체는 반환값을 검증하고 확인하는 andExpect()메소드를 제공한다.
4) andExpect(): 응답을 검증한다. isOK(200)인지 확인한다.
5) jsonPath(): JSON 응답값의 결과를 가져오는 메소드이다. 0번째 배열에 들어있는 객체의 id와 name을 가져오고, 저장된 값과 같은지 확인한다.