본문 바로가기
Spring

[Spring] 슬라이스 테스트 - API 계층, 데이터 액세스 계층 테스트

by jungha_k 2022. 11. 11.

계층 별로 슬라이스!!!

 

슬라이스 테스트 :

각 계층에 구현해 놓은 기능들이 잘 동작하는지 특정 계층만 잘라서 테스트하는 것

 

 

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

댓글