스프링부트 독학-4장 스프링부트 3와 테스트

jaegeunsong97·2023년 8월 30일
0

출처

신서영개발자님의 스프링부트 책

새롭게 알게된 내용 정리

테스트 코드 개념

  • 테스트코드 : 작성한 코드가 의도대로 잘 동작하고 예상치 못한 문제가 없는지 확인할 목적으로 작성하는 코드

  • given -> when -> then

스프링 부트 3와 테스트

  • 스프링 부트 스타터 테스트 목록

    • JUnit : 자바, 단위 테스트 프레임워크
    • Spring Test & Spring Boot Test : 스프링 부트 애플리케이션을 위한 통합 테스트 지원
    • AssertJ : 검증문을 작성하는데 사용되는 라이브러리
    • Hamcrest : 표현식을 이해하기 쉽게 만드는 Matcher 라이브러리
    • Mockito : 테스트에 사용할 가짜인 Mock 객체 쉽게 생성, 관리, 검증을 지원하는 테스트 라이브러리
    • JSONassert : JSON용 어설션 라이브러리
    • JsonPath : JSON 데이터에서 특정 데이터를 선택하고 검색하기 위한 라이브러리
  • JUnit : 자바 언어를 위한 단위 테스트 프레임워크

    • 단위 테스트 : 작성한 코드가 의도대로 작동하는지 작은 단위검증하는 것 -> 보통 메소드
    • 테스트 결과가 직관적
    • 각 테스트에 대해 객체를 만듬 : 각 테스트가 독립적
    • 특징
      • @Test : 각 테스트를 실행할 때마다 테스트를 위한 실행 객체 생성 후 테스트 종료시 자동 삭제
      • 예상 결과를 검증하는 Assertion
      • 사용 방법이 단순, 테스트 코드 작성 시간이 적음
      • 자동 실행, 자체 결과를 빠르게 확인 가능
  • 각 테스트를 실행할 때마다 테스트를 위한 실행 객체 생성 후 테스트 종료시 자동 삭제 검증 코드

    • @BeforeAll : 전체 테스트 시작 전 처음으로 1번 실행 static
    • @BeforeEach : 테스트 케이스를 시작하기 전에 매번 실행
      • 인스턴스에 대해 메소드를 계속 호출 따라서 static X
    • @AfterAll : 전체 테스트 종료 전 처음으로 1번 실행 static
    • @AfterEach : 테스트 케이스를 종료하기 전에 매번 실행
      • 인스턴스에 대해 메소드를 계속 호출 따라서 static X
    • 실행 순서
      • @BeforeAll -> [@BeforeEach -> @Test -> @AfterEach]태스트 개수만큼 반복 -> @AfterAll
import org.junit.jupiter.api.*;

public class JUnitCycleTest {

    @BeforeAll
    static void beforeAll() {
        System.out.println("@BeforeAll");
    }

    @BeforeEach
    public void beforeEach() {
        System.out.println("@BeforeEach");
    }

    @Test
    public void test1() {
        System.out.println("test1");
    }

    @Test
    public void test2() {
        System.out.println("test2");
    }

    @Test
    public void test3() {
        System.out.println("test3");
    }

    @AfterAll
    static void afterAll() {
        System.out.println("@AfterAll");
    }

    @AfterEach
    public void afterEach() {
        System.out.println("@AfterEach");
    }
}
  • AssertJ : JUnit과 함께 사용해 검증문의 가독성을 높여주는 라이브러리
Assertions.assertEquals(sum, a + b); // Assertion
.
.
.
asserThat(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보다 작은 값인지 검증

제대로 테스트 코드 작성

  • @SpringBootTest : @SpringBootApplication이 있는 클래스를 찾고, 그 클래스에 포함된 Bean을 찾은 다음 테스트용 애플리케이션 컨텍스트를 만듬
  • @AutoConfigureMockMvc : MockMvc를 생성하고 자동으로 구성함
    • MockMvc : 애플리케이션은 서버로 배포할 필요 없이 테스트용 MVC 환경을 만들어 요청 및 전송, 응답 기능을 제공함
  • 실제코드
package me.songjaegeun.springbootdeveloper;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
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.ResultActions;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;


@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();
    }

    @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) // 1
                .accept(MediaType.APPLICATION_JSON)); // 2

        // then
        result
                .andExpect(status().isOk())
                .andExpect(jsonPath("$[0].id").value(savedMember.getId()))
                .andExpect(jsonPath("$[0].name").value(savedMember.getName()));
    }
}
  • 주목할 메소드

    • perform() : 요청을 전송하는 역할을 하는 메소드
    • accept() : 요청을 보낼 때 무슨 타입으로 응답을 받을지 결정하는 메소드
    • andExpect() : 응답을 검증
    • jsonPath("$[0].${필드명}") : JSON 응답값의 값을 가져오는 역할을 하는 메소드
  • HTTP 상태코드

코드매핑 메소드설명
200 OKisOk()HTTP 응답코드가 200 OK인지 검증
201 CreatedisCreated()HTTP 응답코드가 201 Created인지 검증
400 Bad RequestisBadRequest()HTTP 응답코드가 400 Bad Request인지 검증
403 ForbiddenisForbidden()HTTP 응답코드가 403 Forbidden인지 검증
404 Not FoundisNotFound()HTTP 응답코드가 404 Not Found인지 검증
400번대 응답 코드is4xxClientError()HTTP 응답코드가 400번대 응답 코드인지 검증
500 Internal Server ErrorisInternalServerError()HTTP 응답코드가500 Internal Server Error인지 검증
500번대 응답 코드is5xxServerError()HTTP 응답코드가 500번대 응답 코드인지 검증
profile
블로그 이전 : https://medium.com/@jaegeunsong97

0개의 댓글