Super Kawaii Cute Cat Kaoani 스프링 부트와 AWS로 혼자 구현하는 웹 서비스(2)

스프링 부트와 AWS로 혼자 구현하는 웹 서비스(2)

2024. 1. 22. 01:30
728x90
SMALL

📌 Test Code

✔ TDD : 테스트가 주도하는 개발
✔ 단위 테스트 : 기능 단위의 테스트 코드를 작성하는 것

 

⚡ 단위 테스트

단위 테스트 장점

✔ 빠른 피드백 - 코드를 수정할 때마다 톰캣을 내렸다가 다시 실행하는 일을 반복하지 않아도 됨
✔ 자동 검증 - System.out.println()을 통해 검증
✔ 개발자가 만든 기능 안전하게 보호 = 기존 기능이 잘 작동되는 것을 보장

 

테스트 코드 작성 프레임워크

  • xUnit
    • JUnit - Java
    • DBUnit - DB
    • CppUnit - C++
    • NUnit - .net
  • 우리 프로젝트에선 자바용인 JUnit5 사용

 

 

📌 Hello Controller 테스트 코드

✔ 일반적으로 패키지 명은 웹사이트 주소의 역순

Application.java

🔶 Application.java : 프로젝트의 메인 클래스

package com.yerin.book.springbootwebservice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringbootWebserviceApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootWebserviceApplication.class, args);
    }

}

@SpringBootApplication

  • 스프링 부트의 자동 설정
  • 스프링 Bean 읽기와 생성을 모두 자동 설정
  • 이 어노테이션이 붙은 곳부터 설정을 읽어감 -> 프로젝트의 최상단에 위치해야 함

SpringApplication.run

  • 내장 WAS 실행
    • 항상 서버에 톰캣을 설치할 필요가 없게 되고, 스프링 부트로 만들어진 Jar 파일(실행 가능한 Java 패키징 파일)로 실행하면 됨
    • 언제 어디서나 같은 환경에서 스프링 부트를 배포할 수 있음

 

HelloController.java

🔶 main/.../com.yerin.book.springbootwebservice/web/HomeController 

package com.yerin.book.springbootwebservice.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 형식으로 반환하는 컨트롤러로 만들어줌
  • @ResponseBody를 각 메소드마다 선언했던 것을 한번에 사용할 수 있게 됨

@GetMapping

  • HTTP Method인 Get의 요청을 받을 수 있는 API를 만들어줌

 

HelloControllerTest.java

📎 단축키 command + shift + T -> Test 클래스 생성
🔶 src/test/.../web/HelloControllerTest

package com.yerin.book.springbootwebservice.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.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;

@ExtendWith(SpringExtension.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));
    }

}

@ExtendWith(SpringExtension.class)

  • JUnit4에선 @RunWith(SpringRunner.class)를 사용했지만 JUnit5에선 위에 어노테이션 사용
  • 테스트를 진행할 때 JUnit에 내장된 실행자 외에 다른 실행자를 실행시킴
    • 여기서는 SpringExtension.class
    • 스프링 부트 테스트와 JUnit 사이에 연결자 역할

@WebMvcTest

  • 여러 스프링 테스트 어노테이션 중, Web(Spring Mvc)에 집중할 수 있는 어노테이션
  • @Controller, @ControllerAdvice 등을 사용 가능
  • 단, @Service, @Component, @Repository 사용 불가능
  • 여기서는 컨트롤러만 사용하기 때문에 선언

@Autowired

  • 스프링이 관리하는 빈 주입받음

private MockMvc mvc

  • 웹 API를 테스트할 때 사용
  • 스프링 MVC 테스트의 시작점
  • 이 클래스를 통해 HTTP GET, POST 등에 대한 API 테스트를 할 수 있음

mvc.perform(get("/hello"))

  • MockMvc를 통해 /hello 주소로 HTTP GET 요청 보냄
  • 체이닝이 지원되어 아래와 같이 여러 검증 기능을 이어서 선언 가능

.andExpect(status().isOk))

  • mvc.perform의 결과를 검증
  • HTTP Header의 Status를 검증
  • 우리가 흔히 알고있는 200, 404, 500 등의 상태를 검증
  • 여기선 OK 즉, 200인지 아닌지 검증

.andExpect(content().string(hello))

  • mvc.perform의 결과를 검증
  • 응답 본문의 내용 검증
  • Controller에서 "hello"를 리턴하기 때문에 이 값이 맞는지 검증

 

실행

SpringbootWebserviceApplication.java 실행

http://localhost:8081/hello 들어가보면 hello가 적혀있는 것을 확인할 수 있음
➡️ HelloController에서 반환한 문자열 (hello)

 

반응형

📌 Lombok

 

✔ Lombok : Getter, Setter, 기본 생성자, toString 등을 어노테이션으로 자동 생성해주는 라이브러리

✔ IntelliJ 2020.03 이후 버전에서는 기본 Plugin으로 Lombok이 설치되어 있음

  •  Plugins-Installed에서 확인
dependencies {
  compileOnly 'org.projectlombok:lombok'
  annotationProcessor 'org.projectlombok:lombok'
}

Gradle 5.x.x 이상

 

HelloController 코드 Lombok으로 전환

🔶 main/.../web/dto/HelloResponseDto 

package com.yerin.book.springbootwebservice.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이 없는 필드는 생성자에 포함하지 않음

 

HelloResponseDtoTest.java

📎 단축키 command + shift + T -> Test 클래스 생성
🔶 src/test/.../web/dto/HelloResponseDtoTest.java

package com.yerin.book.springbootwebservice.web.dto;

import org.junit.jupiter.api.Test;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.junit.jupiter.api.Assertions.*;

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와 같이 메소드를 이어서 사용 가능

isEqualTo

  • assertj의 동등 비교 메소드
  • assertThat에 있는 값과 isEqualTo의 값을 비교해서 같을 때만 성공

-> JUnit의 기본 assertThat이 아닌 assertj의 assertThat사용

 

HelloController.java 코드 추가

@RestController
public class HelloController {

    ...

    @GetMapping("/hello/dto")
    public HelloResponseDto helloDto(@RequestParam("name") String name, @RequestParam("amount")int amount){
        return new HelloResponseDto(name, amount);
    }
}

@RequestParam

  • 외부에서 API로 넘긴 파라미터를 가져오는 어노테이션
  • 외부에서 name이란 이름으로 넘긴 파라미터를 메소드 파라미터 name에 저장

 

HelloControllerTest.java

package com.yerin.book.springbootwebservice.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 static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@ExtendWith(SpringExtension.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;

        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 검증

 

 

스프링 부트와 AWS로 혼자 구현하는 웹 서비스_이동욱 지음 책을 읽고 정리하는 글입니다

 

 

 

 

 


PREV

 

스프링 부트와 AWS로 혼자 구현하는 웹 서비스(1)

📌 1. 인텔리제이로 스프링 부트 시작하기 ⚡ 인텔리제이 소개 강력한 추천기능 훨씬 더 다양한 리팩토리과 디버깅 기능 이클립스의 깃(Git)에 비해 훨씬 높은 자유도 프로젝트 시작할 때 인덱싱

nyeroni.tistory.com

 

NEXT

 

스프링 부트와 AWS로 혼자 구현하는 웹 서비스(3)

📌 JPA JPA : Java 표준 ORM (Object Relational Mapping) ⚡ 패러다임 불일치 문제 관계형 데이터베이스 : 어떻게 데이터를 저장할지에 초점이 맞춰진 기술 객체지향 프로그래밍 : 언어는 메시지를 기반으로

nyeroni.tistory.com

 

728x90
LIST

BELATED ARTICLES

more