본문 바로가기
Test Code

[JUnit] Intro

by junseokoo 2025. 4. 11.

JUnit

  • java를 위한 단위 테스트 프레임워크
    • 단위테스트는 작성한 코드가 의도대로 작동하는지 작은 단위로 검증하는 것. 이때 단위는 보통 메서드 단위
  • 특징
    • 테스트 방식을 구분할 수 있는 애너테이션 제공
    • @Test로 메서드를 호출할 때마다 새 인스턴스 생성, 독립 테스트 가능
    • 예상 결과를 검증하는 Assertions 메서드 제공
    • 사용방법이 단순하며 테스트 코드 작성 시간이 짧다.
    • 자동실행, 자체 결과를 확인하고 즉각적 피드백 제공

JUnitTestCycle

package com.junseok.springbootdevelop.test;

import org.junit.jupiter.api.*;

public class JUnitTestCycle {
    @BeforeAll // 전체 테스트 시작하기전 1회 실행 static
    static void beforAll() {
        System.out.println("@BeforeAll");
    }

    @BeforeEach // 테스트 케이스를 시작하기 전 마다 실행
    public void beforEach() {
        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 // 전체 테스트를 마치고 종료하기전 1회 실행 static
    static void afterAll() {
        System.out.println("@AfterAll");
    }

    @AfterEach // 테스트를 종료할 떄마다 실행
    public void afterEach() {
        System.out.println("@AfterEach");
    }

}

// 결과
// @BeforeAll
// @BeforeEach
// test1
// @AfterEach
// @BeforeEach
// test2
// @AfterEach
// @BeforeEach
// test3
// @AfterEach
// @AfterAll
  • @BeforeAll
    • 전체 테스트를 시작하기 전에 처음으로 딱 한번만 실행한다. 예를들어 데이터베이스를 연결하거나 테스트 환경을 초기화 할때 사용.전체 테스트 실행 주기에서 한 번만 호출해야 하므로 메서드는 static 선언
  • @BeforeEach
    • 테스트 케이스를 시작하기 전에 매번 실행. 예를들어 테스트 메서드에서 사용하는 객체를 초기화 하거나 테스트에 필요한 값을 미리 넣을 때 사용. 각 인스턴스에 대해 메서드를 호출해야 하므로 메서드는 static이 아니어야 한다.
  • @AfterAll
    • 전체 테스트를 마치고 종료하기 전에 한 번만 실행한다. 예를들어 데이터 베이스 연결을 종료하거나 공통적으로 사용하는 자원을 해제할 때 사용. 전체 테스트 실행 주기에서 한 번만 호출되어야 하므로 메서드는 static 선언
  • @AfterEach
    • 각 테스트 케이스를 종료하기 전 매번 실행. 예를들어 테스트 이후 특정 데이터를 삭제 해야할 떄 사용한다. 메서드는 static이 아니어야 한다.

AssertJ

  • JUnit과 함께 사용해 검증문의 가독성을 높여주는 라이브러리이다.
Assertions.assertEquals(a+b, sum);
// 기대값과 비교값이 잘 구분되지 않음

assertThat(a + b).isEqualTo(sum);
// 명확하게 코드를 읽을수 있어 헷갈리지 않는다.
// 지금 예시는 별거 아닐 수 있는데 프로젝트 규모가 커질수록 가독성은 중요한 문제

자주사용하는 메서드

  • isEqualTo(A)
    • A 값과 같은지 검증
  • isNotEqualTo(A)
    • A 값과 다른지 검증
  • contains(A)
    • A 값을 포함 하는지 검증
  • doesNotContain(A)
    • A 값을 포함하지 않는지 검증
  • startWith(A)
    • 접두사가 A인지 검증
  • endsWith(A)
    • 접미사가 A인지 검증
  • isEmpty()
    • 비어있는 값인지 검증
  • isNotEmpty()
    • 비어있지 않은 값인지 검증
  • isPositive()
    • 양수인지 검증
  • isNegative()
    • 음수인지 검증
  • isGreaterThan(1)
    • 1보다 큰 값인지 검증
  • isLessThan(1)
    • 1보다 작은 값인지 검증

Example

package com.junseok.springbootdevelop.test;

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.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@SpringBootTest // SpringBootApplication이 있는 클래스를 찾고 그 클래스에 포함되어 있는 빈을 찾은 뒤에 테스트용 애플리케이션 컨텍스트생성
@AutoConfigureMockMvc // MockMvc를 생성하고 자동으로 구성, 테스트용 MVC 환경을 만들어 요청,전송,응답 제공 // 컨트롤러 테스트
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)
                .accept(MediaType.APPLICATION_JSON));

        // then 테스트 검증 
        result
                .andExpect(status().isOk())
                .andExpect(jsonPath("$[0].id").value(savedMember.getId()))
                .andExpect(jsonPath("$[0].name").value(savedMember.getName()));
    }
}
  • perform()
    • 요청을 전송하는 역할
  • accept()
    • 메세지 요청을 보낼 떄 무슨 타입으로 응답을 받을지 결정 하는 메서드
  • andExpect()
    • 200인지 확인
  • jsonPath("$[0].${필드명})
    • Json 응답값을 가져오는 역할을 하는 메서드 지금 여기선 0번째 배열 id와 name

 

'Test Code' 카테고리의 다른 글

[Jest] Intro  (0) 2025.04.10