슬라이스 테스트 :
각 계층에 구현해 놓은 기능들이 잘 동작하는지 특정 계층만 잘라서 테스트하는 것
API 계층 테스트
: Controller
@SpringBootTest
@AutoConfigureMockMvc
public class ControllerTestDefaultStructure {
@Autowired
private MockMvc mockMvc;
@Test
public void postMemberTest() {
// given - 테스트용 request body 생성
// when - MockMvc 객체로 테스트 대상 Controller 호출
// then - Controller 핸들러 메서드에서 응답으로 수신한 HTTP Status 및 response body 검증
}
}
@SpringBootTest : Spring Boot 기반 애플리케이션을 테스트하기 위한 Application Context 생성
*Application Context : 애플리케이션에 필요한 Bean 객체들 등록되어있음
↕
@WebMvcTest : Controller 테스트에 필요한 Bean 만 ApplicationContext에 등록해줌
실행 속도가 상대적으로 빠름
----------------------------------------------------------------------------------------------------------
@SpringBootTest와 @WebMvcTest 의 차이점 :
@SpringBootTest : 프로젝트에서 사용하는 전체 Bean을 등록
@WebMvcTest : Controller에 필요한 Bean 만 등록 ➡ Mock 객체로 일일이 의존성 제거 필요
----------------------------------------------------------------------------------------------------------
@AutoConfigureMockMvc : Controller 테스트를 위한 애플리케이션의 자동 구성 작업
테스트에 필요한 애플리케이션 구성 자동으로 진행됨
(MockMvc 기능 사용하기 위해서는 필수)
MockMvc - @Autowired 로 DI 주입받는다!
Tomcat 같은 서버 실행하지 않고, Spring 기반 애플리케이션 Controller 를 테스트할 수 있는
Spring MVC 테스트 프레임워크
given - when - then 의 구조
@SpringBootTest
@AutoConfigureMockMvc
class MemberControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private Gson gson;
@Test
void postMemberTest() throws Exception {
// given
// postman의 request body에 포함되는 요청데이터와 동일!
MemberDto.Post post = new MemberDto.Post("hgd@gmail.com",
"홍길동",
"010-1234-5678");
//gson : JSON 변환 라이브러리 (Post 객체를 JSON 포맷으로 변환)
String content = gson.toJson(post);
// when
// perform() : Controller 호출을 위한 세부 정보 有
ResultActions actions =
mockMvc.perform(
post("/v11/members") //HTTP Method, request URL
//응답받을 데이터 타입
.accept(MediaType.APPLICATION_JSON)
//서버에서 처리 가능한 데이터 Content Type
.contentType(MediaType.APPLICATION_JSON)
.content(content) //변환된 JSON 문자열
);
// then ex)1
MvcResult result = actions
.andExpect(status().isCreated()) //Matcher : 기대결과 검증
//response status 201 맞는지 검증
.andReturn(); // 응답 데이터 출력
// then ex)2
MvcResult result = actions
.andExpect(status().isCreated())
//response body ~ request body 일치하는지 검증
//jsonPath() : JSON 형식 개별 프로퍼티에 접근 굿
.andExpect(jsonPath("$.data.email").value(post.getEmail()))
.andExpect(jsonPath("$.data.name").value(post.getName()))
.andExpect(jsonPath("$.data.phone").value(post.getPhone()))
.andReturn();
System.out.println(result.getResponse().getContentAsString());
}
}
데이터 액세스 계층 테스트
지켜야 할 한가지 규칙? : DB 상태를 테스트 케이스 실행 이전으로 되돌려서, 깨끗하게 만듬
public class DataAccessLayerTest {
@Test
public void testA() {
// (1-1) 데이터가 DB에 잘 저장되는지를 테스트하기 위해 한 건의 데이터를 DB에 저장
// (1-2) DB에 잘 저장되었는지 DB에서 조회해서 결과를 확인
}
@Test
public void testB() {
// (2-1) 데이터가 DB에서 잘 조회 되는지를 테스트하기 위해 DB에서 조회
}
//➡ testB 먼저 실행되고 A가 실행될 경우 'failed' 뜸..
//따라서 테스트 케이스의 '독립성' 보장되어야 한다!!!! (db상태 깨끗이)
}
@DataJpaTest //데이터 액세스 계층 테스트 어노테이션
//MemberRepository 기능 사용 위한 Configuration 자동으로 해줌
//@Transactional 포함 - 하나의 tc 종료 ~ db 데이터 rollback
public class MemberRepositoryTest {
@Autowired
private MemberRepository memberRepository; //MemberRepository DI
@Test
public void saveMemberTest() {
// given : member 데이터 준비
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); //리턴멤버객체가 null이 아닌지
//member 객체 필드 = 테스트 데이터와 일치하는지
assertTrue(member.getEmail().equals(savedMember.getEmail()));
assertTrue(member.getName().equals(savedMember.getName()));
assertTrue(member.getPhone().equals(savedMember.getPhone()));
-----------------------------------------------------------------------
@Test
public void findByEmailTest() {
// given
Member member = new Member();
member.setEmail("hgd@gmail.com");
member.setName("홍길동");
member.setPhone("010-1111-2222");
// when
memberRepository.save(member);
//회원정보 중 이메일 정보 잘 조회하는지
Optional<Member> findMember = memberRepository.findByEmail(member.getEmail());
// then
assertTrue(findMember.isPresent()); //조회된 회원정보 null 아닌지 검증
assertTrue(findMember.get().getEmail().equals(member.getEmail()));
//회원 이메일 주소 = 테스트 데이터 이메일 일치하는지 검증
}
}
@DataJpaTest : Spring Data JPA 환경에서 데이터 액세스 계층 테스트 손쉽게 진행 ㄱㄴ
(@Transactional 애너테이션 포함됨 - 하나의 테스트 케이스 종료, 저장된 데이터 rollback)
+ @JdbcTest, @DataJdbcTest
'Spring' 카테고리의 다른 글
[Spring] 애플리케이션 빌드 / 실행 / 배포 (0) | 2022.11.15 |
---|---|
[Spring] API 문서화 - Spring Rest Docs (0) | 2022.11.13 |
[Spring] Mockito, Mock 이란? (0) | 2022.11.10 |
[Spring] 스프링 테스팅(Testing) 中 단위 테스트 - JUnit, Hamcrest (0) | 2022.11.10 |
[Transaction] 트랜잭션이란? / 스프링 지원 - 선언형 방식 트랜잭션 (어노테이션, AOP) (0) | 2022.11.07 |
댓글