본문 바로가기

Studying/스프링부트와 AWS로 혼자 구현하는 웹 서비스

[스프링부트와 AWS로 혼자 구현하는 웹 서비스]_2. (2) 테스트코드와 롬복

1. 롬복이란

 

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

 

build.gradle에 dependencies 부분에다가

compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'

입력하기.

새로 등록했으므로, Reload로 새로고침에서 라이브러리(의존성이라고도 함) 내려받기.

plugins {
	id 'java'
	id 'eclipse'
	id 'org.springframework.boot' version '3.2.5'
	id 'io.spring.dependency-management' version '1.1.4'
}

group = 'com.jojoldu.book'
version = '1.0.4-SNAPSHOT-' + new Date().format("yyyyMMddHHmmss")

repositories {
	mavenCentral()
}

java {
	sourceCompatibility = JavaVersion.VERSION_17
	targetCompatibility = JavaVersion.VERSION_17
}


dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-web'
	compileOnly 'org.projectlombok:lombok'
	annotationProcessor 'org.projectlombok:lombok'

	testImplementation 'junit:junit:4.13.2'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.withType(JavaCompile) {
	options.encoding = 'UTF-8'
}

 

롬복 플러그인 설치하기 위해서는 단축키로 플러그인 Action을 검색.

(윈도우 : Ctrl + Shift + A / 맥 : Command + Shift + A)

Plugins Action 선택하면 플러그인 설치 팝업이 나옴.

 

클릭하고 들어가서 Marketplace 탭 클릭 후 lombok 검색.

install 버튼 클릭하여 설치 진행하면 Restart IDE 클릭해서 인텔리제이를 재시작하기.

 

재시작하면 lombok에 대한 설정을 해줘야 함.

File - Settings - Build, Excution, Deployment - Compiler - Annotation Processors 들어간 뒤, Enable annotation processing 체크

 

2. Hello Controller 코드를 롬복으로 전환하기

 

기존 코드를 롬복을 변경해 보겠다.

지금처럼 작은 규모가 아닌 큰 규모의 프로젝트였다면 롬복으로 전환할 때 어떤 기능이 제대로 작동될지 안 될지 예측하기 어려우므로 쉬운 일은 아님. 하지만 우리는 앞서 테스트 코드를 통해 문제 발생 여부를 쉽게 확인할 수 있게 됨.따라서 크게 걱정할 것은 없음.

 

먼저 src / main / java / springboot / web 아래에 dto 패키지 추가. 앞으로 모든 응답 Dto는 이 패키지에 추가할 것임. 만든 패키지에 HelloResponseDto 클래스 생성.

 

만든 클래스에 아래와 같이 코드 작성하기.

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 필드가 포함된 생성자 생성.

 - final이 없는 필드는 생성자에 포함되지 않음.

 

이 Dto에 적용된 롬복이 잘 작동하는지 간단한 테스트 코드 작성.

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

import org.junit.Test;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

public class HelloResponseDtoTest {
    
    @Test
    public void functionTestLombok() {
        
        // given
        String name = "test01";
        int amount = 1000;
        
        // when
        HelloResponseDto dto = new HelloResponseDto(name, amount);
        
        // then
        assertThat(dto.getName()).isEqualTo(name);
        assertThat(dto.getAmount()).isEqualTo(amount);
    }
}

!설명!

 

assertThat

 - assertj라는 테스트 검증 라이브러리의 검증 메서드.

 - 검증하고 싶은 대상을 메서드 인자로 받음.

 - 메서드 체이닝이 지원되어 isEqualTo와 같이 메서드를 이어서 사용 가능.

 

isEqualTo

 - assertj의 동등 비교 메서드.

 - assertThat에 있는 값과 isEqualTo의 값을 비교해서 같을 때만 성공.

 

여기에서는 Junit의 기본 assertThat이 아닌, assertj의 assertThat을 사용.

assertj 역시 Junit에서 자동으로 라이브러리를 등록해 줌.

assertj의 장점은 다음과 같음.

 - CoreMatcherrs와 달리 추가적으로 라이브러리가 필요하지 않음.

 - 자동완성이 좀 더 확실하게 지원됨.

 

코드를 작성했으면 테스트 메서드를 실행해 보기.

 

그럼 다음과 같이 성공했다고 뜸.

정상적으로 기능이 수행되는 것을 확인할 수 있음.

롬복의 @Getter로 get 메서드가, @RequiredArgsConstructor로 생성자가 자동으로 생성되는 것이 증명됨.

 

그럼 HelloController에도 새로 만든 ResponseDto 사용하도록 코드 추가하기.

package com.jojoldu.book.springboot.web;

import com.jojoldu.book.springboot.web.dto.HelloResponseDto;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @GetMapping("/hello")
    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(@RequestParam("name"))이란 이름으로 넘긴 파라미터를 메서드 파라미터 name(String name)에 저장하게 됨.

 

name과 amount는 API를 호출하는 곳에서 넘겨준 값들임.

추가된 API를 테스트하는 코드를 HelloControllerTest에 추가하기.

package com.jojoldu.book.springboot.web;

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 org.springframework.test.web.servlet.ResultActions;

import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;


@RunWith(SpringRunner.class)
@WebMvcTest(controllers = HelloController.class)
public class HelloControllerTest {

    @Autowired
    private MockMvc mvc;

    @Test
    public void returnHello() throws Exception {
        String hello = "hello";

        mvc.perform(get("/hello"))
                .andExpect(status().isOk())
                .andExpect(content().string(hello));
    }

    @Test
    public void returnHelloDto() throws Exception {
        String name = "test01";
        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 응답값을 필드별로 검증할 수 있는 메서드.

 - $를 기준으로 필드명 명시.

 - 여기서는 name과 amount를 검증하니 $.name, $.amount로 검증

 

추가된 코드를 테스트 진행하면 JSON이 리턴되는 API 역시 정상적으로 테스트가 통과되는 것을 확인할 수 있음.