대부분의 서비스 회사가 테스트 코드에 관해 요구함, 절대 빠질 수 없는 테스트 코드
2.1 테스트 코드 소개
TDD : 테스트가 주도하는 개발

단위 테스트 : 기능 단위의 테스트 코드를 작성하는 것, TDD와 달리 테스트 코드를 꼭 먼저 작성 X, 순수하게 테스트 코드만 작성
이번 장에서 배우는 것 -> 단위 테스트 코드
단위 테스트 코드를 작성함으로써 얻는 이점
- 개발단계 초기에 문제를 발견하게 도와줌
- 개발자가 나중에 코드를 리팩토링하거나 라이브러리 업그레이드 등에서 기존 기능이 올바르게 작동하는지 확인 가능
- 기능에 대한 불확실성 감소
- 시스템에 대한 실제 문서 제공
필자의 경험담
- 빠른 피드백
- 자동검증
- 개발자가 만든 기능을 안전하게 보호해줌
테스트 코드 작성은 100% 익혀야 할 기술이자 습관이다 !!
테스트 코드 작성을 도와주는 프레임워크 : 대중적으로 xUnit
대표적인 xUnit 프레임워크
- JUnit - JAVA
- DBUnit - DB
- CppUnit - C++
- NUnit - .net
2.2 Hello Controller 테스트 코드 작성하기
패키지 생성
패키지 생성 - com.jojoldu.book.springboot
일반적으로 패키지명 : 웹 사이트 주소의 역순으로
클래스 생성
패키지 아래에 Java 클래스 생성 - Application
package com.jojoldu.book.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Application 클래스 : 앞으로 만들 프로젝트의 메인 클래스
@SpringBootAppplication : 스프링 부트의 자동 설정, 스프링 Bean 읽기와 생성을 모두 자동으로 설정
-> 이 위치부터 설정을 읽어가기 때문에 항상 프로젝트의 최상단에 위치해야함
SpringApplication.run : 내장 WAS 실행
내장 WAS
별도로 외부에 was를 두지 않고 애플리케이션을 실행할 때 내부에서 was 실행
항상 서버에 톰캣 설치할 필요 없음
스프링 부트에서는 내장 was 사용하는 것 권장 : 언제 어디서나 같은 환경에서 스프링 부트 배포 가능
Controller 만들기
위에서 만든 패키지 하위에 web 패키지 생성 -> 컨트롤러와 관련된 클래스들은 이 패키지에
package com.jojoldu.book.springboot.web;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController //컨트롤러를 JSON을 반환하는 컨트롤러로 만들어줌
public class HelloController {
@GetMapping("/hello") //HTTP Method인 Get의 요청을 받을 수 있는 api 생성
public String hello() {
return "hello";
}
}
테스트 코드로 검증
테스트 코드를 작성한 클래스 생성 : HelloControllerTest
package com.jojoldu.book.springboot.web;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.Matchers.is;
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.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ExtendWith(SpringExtension.class)
//Web에 집중할 수 있는 어노테이션
@WebMvcTest(controllers = HelloController.class)
public class HelloControllerTest {
@Autowired
private MockMvc mvc;
@Test
public void hello가_리턴된다() throws Exception {
String hello = "hello";
mvc.perform(get("/hello"))
.andExpect(status().isOk())
.andExpect(content().string(hello));
}
@Test
public class HelloControllerTest {
//스프링이 관리하는 빈 주입
@Autowired
//스프링 MVC 테스트의 시작, 웹 API 테스트
private MockMvc mvc;
@Test
public void hello가_리턴된다() throws Exception {
String hello = "hello";
// /hello 주소로 HTTP GET 요청
mvc.perform(get("/hello"))
//HTTP 헤더의 status 검증
.andExpect(status().isOk())
//응답 본문의 내용 검증
.andExpect(content().string(hello));
}
}
@WebMvcTest : @Controller, @ControllerAdvice 사용 가능, @Service, @Component, @Repository 사용 불가
테스트 코드 실행
Run 'hello가_리턴된다()' 클릭
수동 검증) Application.java 파일에서 main 메소드 실행 -> localhost:8080/hello 접속해보기
중요 !! 절대 수동으로 검증하고 테스트 코드를 작성하진 않음
2.3 롬복 소개 및 설치하기
롬복 : 자바 개발 시 자주 사용하는 코드를 어노테이션으로 자동 생성해 줌
intellij에서는 build.gradle에 코드를 추가하는 방법으로 쉽게 추가 가능
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
책에서는 compile()으로 하라고 했는데 오류나서 찾아봤더니 gradle 버전이 5.x 이상이어야 한다고 한다.
관련 링크 : https://deeplify.dev/back-end/spring/lombok-required-args-constructor-initialize-error
[스프링/Spring] Lombok: variable not initialized in the default constructor
RequiredArgsConstructor 사용 시 not initialized in the default constructor 에러가 발생하는 원인과 해결 방법에 대해서 소개합니다.
deeplify.dev
코드 추가 후 marketplace에서 롬복 다운로드
Intellij 재시작 후 settings> Build > Compiler > Annotation Processors
enable annotation processing 체크
2.4 Hello Controller 코드를 롬복으로 전환하기
web > dto > HelloResponseDto
import lombok.Getter;
import lombok.RequiredArgsConstructor;
// 선언된 모든 필드의 get 메소드 생성
@Getter
//선언된 모든 final 필드가 포함된 생성자 생성
@RequiredArgsConstructor
public class HelloResponseDto {
private final String name;
private final int amount;
}
테스트 코드 작성
HelloResponseDtoTest
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class HelloResponseDtoTest {
@Test
public void 롬복_기능_테스트() {
//given
String name = "test";
int amount = 1000;
//when
HelloResponseDto dto = new HelloResponseDto(name, amount);
//then
assertThat(dto.getName()).isEqualTo(name);
assertThat(dto.getAmount()).isEqualTo(amount);
}
}
assertThat : assertj의 검증 메소드, 검증하고 싶은 대상을 메소드 인자로 받음
isEqualTo : assertj의 동등 비교 메소드, assertThat에 있는 값과 비교해서 같을 때만 성공
HelloController
@RestController //컨트롤러를 JSON을 반환하는 컨트롤러로 만들어줌
public class HelloController {
@GetMapping("/hello") //HTTP Method인 Get의 요청을 받을 수 있는 api 생성
public String hello() {
return "hello";
}
@GetMapping("/hello/dto")
public HelloResponseDto helloDto(@RequestParam("name") String name, @RequestParam("amount") int amount) {
return new HelloResponseDto(name, amount);
}
}
@RequestParam : 외부에서 api로 넘긴 파라미터 가져오는 어노테이션
여기선 외부에서 가져온 값 name에 저장
HelloControllerTest
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.Matchers.is;
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.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringRunner.class)
@WebMvcTest(controllers = HelloController.class)
public class HelloControllerTest {
@Autowired
private MockMvc mvc;
@Test
public void hello가_리턴된다() throws Exception {
String hello = "hello";
mvc.perform(get("/hello"))
.andExpect(status().isOk())
.andExpect(content().string(hello));
}
@Test
public void helloDto가_리턴된다() throws Exception {
String name = "hello";
int amount = 1000;
//param : api 테스트 할때 사용할 요청 파라미터 설정, String만 허용
mvc.perform(get("/hello/dto").param("name", name).param("amount", String.valueOf(amount)))
.andExpect(status().isOk())
//jsonPath : JSON 응답값을 필드별로 검증
.andExpect(jsonPath("$.name", is(name)))
.andExpect(jsonPath("$.amount", is(amount)));
}
}
'Group Study (2023-2024) > Spring 입문' 카테고리의 다른 글
[스프링 입문] 5주차 chap 06 - AWS 서버 환경을 만들어보자 - AWS EC2 (0) | 2023.12.25 |
---|---|
[스프링 입문] 4주차 chap 05 - 스프링 시큐리티와 OAuth 2.0으로 로그인 기능 구현하기 (1) | 2023.11.27 |
[스프링 입문] 3주차 chap 04 - 머스테치로 화면 구성하기 (1) | 2023.11.16 |
[Spring 입문] 1주차 chap 03 - 스프링 부트에서 JPA로 데이터베이스 다뤄보자 (0) | 2023.11.10 |
[스프링 입문] 1주차 chap 01 - 인텔리제이로 스프링 부트 시작하기 (0) | 2023.11.05 |