티스토리 뷰

이동욱 님의 '스프링부트와 AWS로 혼자 구현하는 웹 서비스' 책 내용을 정리한 것입니다.

 

1장 인텔리제이로 스프링부트 시작하기

build.gradle

- ext: 전역변수 사용

- repositories: 각종 의존성들을 어떤 원격 저장소에서 받을지 결정

  • mavenCentral: 본인이 만든 라이브러리를 업로드 하기 위한 과정과 설정 필요
  • jcenter: 라이브러리 업로드 수월

- dependencies: 프로젝트 개발에 필요한 의존성들을 선언

  • io.spring.dependency-management: 스프링부트의 의존성들을 관리해주는 플러그인

 

.idea 파일은 모든 커밋 대상에서 제외!

 

.gitignore 파일

- 깃에서 특정 파일 혹은 디렉토리를 관리 대상에서 제외할 때 사용

- intellj에서 지원이 없어서 플러그인 사용

 

2장 스프링부트에서 테스트 코드를 작성하자

TDD - 테스트가 주도하는 개발

✔️ 테스트 코드를 먼저 작성하는 것부터 시작!

TDD Cycle

  • RED: 항상 실패하는 테스트 먼저 작성
  • GREEN: 테스트가 통과하는 프로덕션 코드 작성
  • REFACTOR: 테스트가 통과하면 프로덕션 코드를 리팩토링

단위테스트

✔️ 기능 단위의 테스트 먼저 작성!

  • 테스트 코드를 먼저 작성하는 것이 아니고 리팩토링도 포함하지 ❌
  • 순수하게 "테스트 코드만" 작성

➡️ 개발단계 초기에 문제 발견

➡️ 리팩토링 혹은 라이브러리 업그레이드 시 올바르게 작동하는지 확인 가능

➡️ 불확실성 감소

➡️ 시스템에 대한 실제 문서 제공 (단위 테스트 자체가 문서로 사용 가능)

 

프로젝트의 메인 클래스 - ProjectApplication.java

package com.example.project;

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

@SpringBootApplication
public class ProjectApplication {

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

}

 

@SpringBootApplication

- 스프링부트의 자동 설정

- 스프링 빈 읽고 생성하기 모두 자동 설정

- 이 어노테이션이 있는 위치부터 설정을 읽기 시작

 

SpringApplication.run()

- 내장 WAS(Web Application Server) 실행

- 외부 WAS 두지 않고 내부에서 실행하여 톰캣이 필요하지 않음

 

언제 어디서나 같은 환경에서 스프링부트를 배포 가능하기 때문에 내부 WAS 환경 권장!

 

컨트롤러 - HelloController.java

package com.example.project.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

Controller를 JSON으로 반환한다.

(예전에는 메서드마다 @ResponseBody를 선언하였음)

 

@GetMapping

HTTP Method를 Get의 요청으로 받을 수 있는 API

 

⬇️ 테스트 코드로 검증해보자!

 

HelloControllerTest.java

package com.example.project.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) // JUnit5
@WebMvcTest(controllers = HelloController.class)
public class HelloControllerTest {

    @Autowired
    private MockMvc mvc;

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

        mvc.perform(get("/hello"))
		// mvc.perform의 결과 검증
                .andExpect(status().isOk()) // HTTP Header의 Status 검증 (200인지 아닌지)
                .andExpect(content().string(hello)); // 응답 본문의 내용 검증 (컨트롤러에서 "hello" 반환하기 때문에 값이 맞는지)
    }
}

 

실행결과 성공!

 

@ExtendWith(SpringExtension.class)

- 테스트 진행 시 JUnit에 내장된 다른 실행자 실행

- 스프링부트 테스트와 JUnit 사이 연결자 역할

 

@WebMvcTest

Web에 집중할 수 있는 어노테이션

사용 가능: @Controller, @ControllerAdvice

사용 불가능: @Service, @Component, @Repository

 

서버 실행 시

⬇️ 롬복을 설치하고 HelloController를 롬복으로 전환해보자!

 

HelloResponseDto.java

package com.example.project.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 필드가 포함된 생성자를 생성한다.

 

HelloResponseDtoTest.java

package com.example.project.web.dto;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

public class HelloResponseDtoTest {

    @Test
    public void 롬복_기능_테스트() {
        // given
        String name = "test";
        int amount = 1000;

        // when
        HelloResponseDto dto = new HelloResponseDto(name, amount);

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

실행결과 성공!

 

assertThat()

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

- 검증하고 싶은 대상을 인자로 받아서 값을 비교

 

HelloController.java

package com.example.project.web;

import com.example.project.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로 넘긴 파라미터를 가져온다.

 

HelloControllerTest.java

package com.example.project.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.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;


@ExtendWith(SpringExtension.class) // JUnit5
@WebMvcTest(controllers = HelloController.class)
public class HelloControllerTest {

    @Autowired
    private MockMvc mvc;

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

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

    @Test
    public void helloDto_return() 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 응답값을 필드별로 검증한다.

 

 

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함