728x90
테스트 코드?
테스트 코드란 작성한 코드가 의도대로 잘 동작하고 예상치 못한 문제가 없는지 확인할 목적으로 작성하는 코드
테스트 코드의 패턴
given-when-then 패턴을 사용한다. 이 패턴은 테스트 코드를 세 단계로 구분해 작성하는 방식이다
- given : 테스트 실행을 준비하는 단계
- when : 테스트를 진행하는 단계
- then : 테스트 결과를 검증하는 단계
JUnit을 사용한 테스트
JUnit이란?
자바 언어를 위한 단위 테스트 프레임워크
단위 테스트?
작성한 코드가 의도대로 작동하는지 작은 단위로 검증하는 것. 이때 단위는 보통 메서드가 된다.
JUnit특징
- 테스트 방식을 구분할 수 있는 애너테이션 제공
- @Test 애너테이션으로 메서드를 호출할 때 마다 새 인스턴스를 생성, 독립 테스트 가능
- 예상 결과를 검증하는 어설션 메서드 제공
- 사용 방법이 단순, 테스트 코드 작성 시간이 적음
- 자동실행, 자체 결과를 확인하고 즉각적인 피드백 제공
JUnit 사용해보기
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
public class JUnitTest {
@DisplayName("1 + 2는 3이다") // 테스트 이름
@Test // 테스트 메서드
// 각 테스트를 실행할때 마다 테스트를 위한 실행 객체를 만들고 테스트가 종료되면 실행 객체 삭제
public void junitTest(){
int a = 1;
int b = 2;
int sum = 3;
Assertions.assertEquals(sum, a + b); // 값이 같은지 확인
}
JUnit 어노테이션
테스트는 어노테이션에 따라서 실행 순서가 정해진다
import org.junit.jupiter.api.*;
public class JUnitCycleTest {
// 전체 테스트를 시작하기 전에 1회 실행하므로 메서드는 static 선언
@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");
}
// 전체 테스트를 마치고 종료하기 전에 1회 실행하므로 메서드는 static으로 선언
@AfterAll
static void afterAll() {
System.out.println("@AfterAll");
}
// 테스트 케이스를 종료하기 전마다 실행
@AfterEach
public void afterEach() {
System.out.println("@AfterEach");
}
}
@BeforeAll
전체 테스트를 시작하기 전에 처음으로 한 번만 실행 예를 들어 데이터베이스를 연결해야 하거나 테스트 환경 조성
이 어노테이션은 전체 테스트 실행 주기에서 한번만 실행되기 때문에 static 선언
@BeforeEach
테스트 케이스를 시작하기 전에 매번 실행. 객체를 초기화 하거나 테스트에 필요한 값을 미리 넣을때 사용함
@AfterAll
전체 테스트를 마치고 종료하기 전에 한 번만 실행. 데이터베이스 연결을 종료할 때나 공통적으로 사용하는 자원을 해제할 때 사용 전체 테스트 실행 주기에서 한번만 호출되어야 하므로 메서드를 static 선언
@AfterEach
각 테스트를 종료하기 전에 매번 실행. 특정 테스트 이후에 특정 데이터를 삭제해야하는 경우 사용
JUnit과 사용하기 좋은 AssertJ
Assert J??
JUnit과 함께 사용해 검증문의 가독성을 높여주는 라이브러리
앞서 작성한 테스트 코드의 Assertion은 기댓값과 실제 비교값을 명시하지 않으므로 비교대상이 헷갈림!
Assertions.assertEquals(sum, a+b) // 가독성 나쁨
assertThat(a+b).isEqualTo(sum) // 가독성 좋음!
테스트 코드 제대로 작성해보기
package com.rowoon.studyBoot;
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.junit.jupiter.api.Assertions.*;
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
@AutoConfigureMockMvc
class TestControllerTest {
// 서버의 배포 없이 테스트용 MVC 환경을 만들어 요청 및 전송 응답 기능을 제공
// 즉, 컨트롤러를 테스트할때 사용하는 클래스
@Autowired
protected MockMvc mockMvc;
@Autowired
private WebApplicationContext context;
@Autowired
private MemberRepository memberRepository;
@BeforeEach
public void setMockMvc() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
}
@AfterEach
public void cleanUp() {
memberRepository.deleteAll();
; }
@DisplayName("getAllMembers: 아티클 조회에 성공한다.")
@Test
public void getAllMembers() throws Exception {
// given
// 원하는 api 주소
final String url = "/test";
// 멤버 객체 저장
Member savedMember = memberRepository.save(new Member(1L, "홍길동"));
// when
// perform() : 요청을 전송하는 역할을 하는 메서드 url 변수에 저장된 api 주소로 요청을 전송한다
// .accept() : 요청을 보낼때 무슨 타입으로 받을지 설정
final ResultActions result = mockMvc.perform(get(url) // 1
.accept(MediaType.APPLICATION_JSON)); // 2
// then
// 응답코드가 isOK() => 200번대인지 확인
result
.andExpect(status().isOk())
// 0번째 index의 id와 name 값을 가져오고 값이 같은지 확인한다
.andExpect(jsonPath("$[0].id").value(savedMember.getId()))
.andExpect(jsonPath("$[0].name").value(savedMember.getName()));
}
}
HTTP 주요 응답 코드 정리
코드 매핑 메서드
200 OK | isOk() |
201 Create | isCreated() |
400 Bad Request | isBadRequest() |
403 Forbidden | isForbidden() |
404 Not Found | isNotFound() |
400번대 응답 코드 | is4xxClientError() |
500 Internal Server Error | isInternalServerError() |
500번대 응답 코드 | is5xxServerError |
반응형
'Spring, Spring boot' 카테고리의 다른 글
TIL (1) | 2024.01.03 |
---|---|
JPA와 엔티티 (0) | 2023.12.24 |
JPA를 활용한 기본적인 CRUD 해보기 (0) | 2023.10.26 |
트랜잭션 (1) | 2023.10.26 |
JPA 동작원리 (0) | 2023.10.25 |