본문 바로가기
Java/Spring Boot

[Spring Boot] Test Code 작성 + 롬복(LomBok)

by 깨준 2024. 9. 12.

1. 테스트 코드 소개

1) TDD이란?

테스트가 주도하는 개발로 TDD ≠ 단위 테스드(Unit Test)

 

2) 단위 테스트(Unit Test)란?

TTD의 첫 번째 단계인 기능 단위의 데스트 코드를 작성하는 것

 

3) 테스트 코드의 장점

  • 개발단계 초기에 문제를 발견
  • 개발자나 나중에 코드를 리팩터링 하거나 라이브러리 업그레이드 등에서 기존 기능이 올바르게 작동하는지 확인
  • 기능에 대한 불확실성을 감소
  • 시스템에 대한 실제 문서를 제공

2. JUnit를 사용하여 테스트 코드 작성

1) 프로젝트 메인 클래스 생성하기

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

 

  • @SpringBootApplication: 스프링 부트의 자동 설정, 스프링 Bean 읽기와 생성을 모두 자동 설정
  • SpringApplication.run: 내장 WAS를 실행

내장 WAS란?

별도로 외부에 WAS를 두지 않고 애플리케이션을 실행할 때 내부에서 WAS를 실행하는 것

-> 이렇게 되면 항상 서버에 톰캣을 설치할 필요없이 스프링부트로 만들어진 Jar 파일로 실행 가능

 

스프링 부트는 내장 WAS를 사용하는 것을 권장 -> 언제 어디서나 같은 환경에서 스프링 부트를 배포 가능

 

2) Hello Controller 생성하기

package com.jojoldu.book.springboot.web;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }

 

  • @RestController: 컨트롤러를 JSON을 반환하는 컨트롤러로 만든다.
  • @GetMapping: Get 요청을 받을 수 있는 API를 만들어 준다.

3) Hello Controller 테스트 코드 작성하기

package com.jojoldu.book.springboot.web;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MockMvc;

import static org.hamcrest.Matchers.is;
import org.springframework.test.web.servlet.ResultActions;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;


@ExtendWith(SpringExtension.class)
@WebMvcTest
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));
    }
}
  • @ExtendWith(SpringExtension.class): 스프링 부트 테스트와 JUnit 사이에 연결자 역할을 한다.
  • @WebMvcTest: Web(Spring MVC)에 집중할 수 있다. 컨트롤러만 사용하기 때문에 선언한다.
  • @Autowired: 스프링이 관리하는 빈(Bean) 주입받음.
  • private MockMvc mvc: 웹 API를 테스트할 때 사용, 스프링 MVC 테스트의 시작점
  • mvc.perform(get("/hello")): MockMvc를 통해 /hello 주소로 HTTP GET 요청
  • .andExpect(status().isOk()): mvc.perform의 결과 검증(HTTP Header의 Status 검증)
  • .andExpect(content().string(hello)): mvc.perform의 결과 검증(응답 본문의 내용 검증)

실행 결과


3. 롬복 소개 및 설치

1) 롬복(LomBok)이란?

자바 개발할 때 자주 사용하는 코드 Getter, Setter, 기본생성자, toString 등을 어노테이션으로 자동 생성

 

2) 롬복(LomBok) 설치

 

build.gradle에 코드 추가

compile('org.projectlombok:lombok')

 

플러그인 Action에서 lombok 검색 후 다운로드

 

마지막으로 setting -> Build, Execution, Deployment -> Compiler -> Annotation Processors에서

Enable annotation processing 체크


4. Controller 코드를 롬복으로 전환

1) Dto 패키지 생성 후 HelloReponseDto 생성

package com.jojoldu.book.springboot.web.dto;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public class HelloResponseDto {

    private final String name;
    private final int amount;
}
  • @Getter: 선언된 모든 필드의 get 메서드를 생성
  • @RequiredArgsConstructor: 선언된 모든 final 필드가 포함된 생성자를 생성

2) HelloReponseDto 테스트 코드 작성

package com.jojoldu.book.springboot.web.dto;

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에 있는 값과 isEqualTo의 값을 비교해서 같을 때만 성공

실행 결과

 

3) HelloController에 ResponseDto 코드 추가하기

@GetMapping("/hello/dto")
    public HelloResponseDto helloDto (@RequestParam("name") String name, @RequestParam ("amount") int amount) {
        return new HelloResponseDto(name, amount);
    }
  • RequestParam: 외부에서 API로 넘기 파라미터를 가져오는 어노테이션으로 외부에서 name(@RequestParam("name"))이란 이름으로 넘긴 파라미터를 메소드 파라미터 name(String name)에 저장

4) HelloControllerTest에 ResponseDto 코드 추가하기

@Test
    public void helloDto가_리턴된다() throws Exception {
        String name = "hello";
        int amount = 1000;

        mvc.perform(
                        get("/hello/dto")
                                .param("name", name)
                                .param("amount", String.valueOf(amount)))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.name", is(name)))
                .andExpect(jsonPath("$.amount", is(amount)));
    }
  • param: API 테스트할 때 사용될 요청 파라미터를 설정(단, 값은 String만 허용)
  • jsonPath: JSON 응답값을 필드별로 검증할 수 있는 메소드로 $를 기준으로 필드명을 명시

실행 결과