Over the limit

[스프링 부트와 AWS로 혼자 구현하는 웹 서비스] 2장 본문

Web

[스프링 부트와 AWS로 혼자 구현하는 웹 서비스] 2장

ellapk 2022. 4. 7. 08:28

-테스트 코드 작성에 관하여-

 

1. TDD와 다른 테스트 코드

 

 TDD는 테스트가 주도하는 개발을 이야기 한다.

반면 단위 테스트는 TDD의 첫 번째 단계인 기능 단위의 테스트 코드를 작성하는 것을 말한다.

앞으로 다룰 테스트 코드는 모두 '단위 테스트'를 의미함을 알기!

 

 

2. 테스트 코드를 작성하는 이유?

  • 개발 단계 초기에 문제를 발견하게 도와준다
  • 나중에 개발자가 코드를 리팩토링하거나 라이브러리를 업그레이드 할 때 기존 기능이 올바르게 작동하는지 확인할 수 있다. (EX. 회귀 테스트)
  • 시스템에 대한 실제 문서를 제공한다
  • 빠른 피드백을 제공해준다.
  • 개발자가 만든 기능을 보호해준다.

나도 개발을 하며 디버깅을 할 때 매번 서버를 올린 후 HTTP 요청 후에 System.out.println()으로 확인했던 기억이 있는데, 테스트 코드를 사용하면 이러한 수동 검증 과정은 필요없어 질 것이다.

 

3. 테스트 코드 작성해보기

package com.web.community.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 읽기와 생성을 모두 자동으로 설정한다.

여기서 @SpringBootApplication 이 있는 위치부터 설정을 읽어가기 때문에 이 클래스는 항상 프로젝트의 최상단에 위치해야 한다는 주의점이 있다.

 

또한 아까 테스트 코드를 사용하면 수동 검증 과정이 필요없다고 하였는데,

main 메소드에서 실행하는 SpringApplication.run으로 내장 WAS을 사용하여 항상 서버에 무언가를 올릴 필요가 없게 된다.

여기서 WAS는 되도록이면 내장 WAS를 사용하여 '언제 어디서나 같은 환경에서 스프링 부트를 배포' 할 수 있어야 한다. 외장 WAS는 매번 종류나 버전 설정을 신경써야 하기 때문이다.

 

 

 

컨트롤러 작성

package com.web.community.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

HTTP Method 인 Get의 요청을 받을 수 있는 API를 만들어 준다.

 

 

 

테스트 클래스

main 폴더 아래의 java package들을 만들어 준 것과 같은 구조로 생성 후에 HelloControllerTest 파일을 

만들어준다. 

 

 

package com.web.community.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 static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
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 return_hello() throws Exception {
        String hello = "hello";

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

 

 

성공!

 

 

3. 롬복 알기

롬복 Lombok이란 Java라이브러리로 반복되는 getter, setter, toString 등의 반복 메서드 작성 코드를 줄여주는 라이브러리다. 두번씩 쓰지 말고 한번만 쓰도록 도와준다.

 

어노테이션?

Lombok은 여러가지 @어노테이션 을 제공하며 이를 기반으로 반복 소스코드를 컴파일 할 때

생성해주며 동작하는 라이브러리다.

 

 

 

HelloController 코드를 롬복으로 전환하기

 

기존에 HelloController 코드를 작성한 바 있다. 여기에 다양한 @어노테이션을 제공해주는 롬복으로 프로젝트를 전환하고 싶을 때, 걱정 없이 마음대로 진행해도 될까?

 

정답은 된다!

왜냐면 우리는 현재 테스트 코드를 기반으로 프로젝트를 작성하고 있기 때문이다.

롬복으로 변경하고 문제가 생기는지는 테스트 코드만 돌려보면 알 수 있다.

 

package com.web.community.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이 없는 필드는 생성자에 포함 X

 

 

 

package com.web.community.springboot.web.dto;

import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;

public class HelloResponseDtoTest {
    @Test
    public void lombok_test() {
        String name = "test";
        int amount = 1000;

        HelloResponseDto dto = new HelloResponseDto(name, amount);

        assertThat(dto.getName()).isEqualTo(name);
        assertThat(dto.getAmount()).isEqualTo(amount);
    }
}

@asserThat

assertj라는 테스트 검증 라이브러리의 검증 메소드

검증하고 싶은 대상을 메소드 인자로 받는다.

메소드 체이닝이 지원되어 isEqualTo와 같이 메소드를 이어서 사용한다.

 

@isEqualTo

assertj의 동등 비교 메소드

 

성공했다! 이 말은 즉슨

롬복의 @Getter로 get메소드가, @RequiredArgsConstructor로 생성자가 자동으로 생성되었다는 뜻이다.

 

이제 계획대로 HelloController에 새로 만든 ResponseDto를 사용하도록 코드를 추가하면 된다.