메서드 단위로 진행하는 테스트. 단위 테스트를 하는 이유는 매번 HTTP 요청을 보내는 것은 비효율적이기 때문이다.
테스트의 가독성을 높이기 위한 패턴
자바 애플리케이션을 테스트 하기 위한 테스트 프레임워크이다.
JUnit 기본 구조
@Test
public void calculateStampCountTest() {
// given
int nowCount = 5;
int earned = 3;
int expected = 8;
// when
int actual = StampCalculator.calculateStampCount(nowCount, earned);
// then
Assertions.assertEquals(expected, actual);
}
메서드에 @Test 애너테이션을 사용하고 Given-When-Then 패턴으로 테스트 케이스를 구성한다.
하나의 계층에 구현한 기능들이 잘 동작하는지 특정 계층만 잘라서 하는 테스트.
import com.codestates.member.dto.MemberDto;
import com.google.gson.Gson;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest
@AutoConfigureMockMvc
class MemberControllerTest2 {
@Autowired
private MockMvc mockMvc; //테스트에 필요한 가짜 객체
@Autowired
private Gson gson; //JSON 변환 라이브러리
@Test
void postMemberTest() throws Exception {
// given
MemberDto.Post post = new MemberDto.Post("hgd@gmail.com",
"홍길동",
"010-1234-5678");
String content = gson.toJson(post);
// when
ResultActions actions =
mockMvc.perform(
post("/v11/members")
.accept(MediaType.APPLICATION_JSON) // 응답 데이터 JSON 타입 설정
.contentType(MediaType.APPLICATION_JSON)
.content(content) // request body 데이터 설정
);
// then
MvcResult result = actions
.andExpect(status().isCreated()) // 201(OK)이 맞는지 검증
.andExpect(jsonPath("$.data.email").value(post.getEmail())) //JSON 형식 응답과 request body 데이터가 일치하는지 검증
.andExpect(jsonPath("$.data.name").value(post.getName()))
.andExpect(jsonPath("$.data.phone").value(post.getPhone()))
.andReturn();
System.out.println(result.getResponse().getContentAsString());
}
}
@SpringBootTest 애너테이션은 애플리케이션 테스트를 위한 애플리케이션 Context를 생성한다. @AutoConfigureMockMvc 애너테이션은 애플리케이션의 자동 구성 작업을 한다.
import com.codestates.member.entity.Member;
import com.codestates.member.repository.MemberRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import static org.junit.jupiter.api.Assertions.*;
@DataJpaTest
public class MemberRepositoryTest {
@Autowired
private MemberRepository memberRepository;
@Test
public void saveMemberTest() {
// given
Member member = new Member();
member.setEmail("hgd@gmail.com");
member.setName("홍길동");
member.setPhone("010-1111-2222");
// when
Member savedMember = memberRepository.save(member);
// then
assertNotNull(savedMember);
assertTrue(member.getEmail().equals(savedMember.getEmail()));
assertTrue(member.getName().equals(savedMember.getName()));
assertTrue(member.getPhone().equals(savedMember.getPhone()));
}
}
@DataJpaTest 애너테이션은 MemberRepository의 기능을 정상적으로 사용하기 위한 Configuration을 Spring이 자동으로 해준다. 이 애너테이션은 @Transactional을 포함하기 때문에 하나의 테스트 케이스 실행이 종료되고 DB에 저장된 데이터는 rollback 처리 된다. 이는 데이터베이스가 초기 상태로 계속 유지된다는 의미이다.