Spring-boot TDD

์žญ์žญ์ดยท2021๋…„ 4์›” 19์ผ
2

Spring-boot

๋ชฉ๋ก ๋ณด๊ธฐ
2/11
post-thumbnail

Spring-boot TDD

๐ŸŽ ๋ชฉ์ฐจ

0. ๊ฐœ์š”

ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ์€ ์ด๊ณณ์„ ์ฐธ์กฐํ•œ๋‹ค.

TDD (Test-driven Development) ๋ž€ ํ…Œ์ŠคํŠธ ์ฃผ๋„ ๊ฐœ๋ฐœ๋กœ์„œ ํ…Œ์ŠคํŠธ๊ฐ€ ์ฃผ๊ฐ€ ๋˜์–ด ๊ฐœ๋ฐœํ•˜๋Š” ๋ฐฉ๋ฒ•๋ก ์ด๋‹ค.
TDD๋ฅผ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ์šฐ๋ฆฌ๋Š”

  • was๋ฅผ ํฌํ•จํ•œ ๋ฌด๊ฑฐ์šด spring-boot์˜ ์žฌ์‹œ์ž‘ ์—†์ด๋„ ์ฝ”๋“œ๋ฐ˜์˜์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
  • print๋ฅผ ์ฐ์ง€ ์•Š์•„๋„ ๊ฒ€์ฆ์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋œ๋‹ค.
  • ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ๋กœ ์ธํ•ด ๊ธฐ์กด ๊ธฐ๋Šฅ์— ์ƒ๊ธฐ๋Š” ๋ฌธ์ œ๋ฅผ ์‚ฌ์ „ ์˜ˆ๋ฐฉํ•  ์ˆ˜ ์žˆ๋‹ค.

1. dependency ์ถ”๊ฐ€

build.gradle์— ๋‹ค์Œ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

dependencies {
  // RestAPI
  implementation 'org.springframework.boot:spring-boot-starter-web'  
  // Test
  testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

test {
	useJUnitPlatform()
}

2. Controller ์ž‘์„ฑ

  1. package ์ƒ์„ฑ
    /web/controllerํด๋”๋ฅผ ๋งŒ๋“ ๋‹ค.
  2. controller class ์ƒ์„ฑ
    ํ•ด๋‹น ํด๋” ์•„๋ž˜์— HelloController.java๋ฅผ ๋งŒ๋“ ๋‹ค.
package com.rivernine.demo.web.controller;

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

@RestController
public class HelloController {

  @GetMapping("/hello")
  public String hello(){
    return "hello";
  }
}
  • @RestController
    • ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ JSON์„ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ํ•ด์ค€๋‹ค.(
    • ๊ธฐ์กด์—๋Š” @ResponseBody๋ฅผ ๋ฉ”์†Œ๋“œ๋งˆ๋‹ค ์„ ์–ธํ•ด ์ฃผ์—ˆ๋‹ค.
  • @GetMapping
    • HTTP method ์ค‘ Get ์š”์ฒญ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” API๋ฅผ ๋งŒ๋“ค์–ด์ค€๋‹ค.
    • ๊ธฐ์กด์—๋Š” @RequestMapping(method = RequestMethod.GET)์„ ์‚ฌ์šฉํ–ˆ์Œ

3. Test ์ž‘์„ฑ

  1. package ์ƒ์„ฑ
    test์•„๋ž˜์— ๋™์ผ ๊ตฌ์กฐ์˜ ํด๋”๋ฅผ ๋งŒ๋“ ๋‹ค. web/controller
  2. test controller class ์ƒ์„ฑ
    ํ•ด๋‹น ํด๋” ์•„๋ž˜์— HelloControllerTest.java๋ฅผ ๋งŒ๋“ ๋‹ค.
package com.rivernine.demo.web.controller;

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 org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;

@ExtendWith(MockitoExtension.class)
@WebMvcTest
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));
  }
}
  • @ExtendWith
    • Spring-boot ํ…Œ์ŠคํŠธ์™€ JUnit์‚ฌ์ด์˜ ์—ฐ๊ฒฐ์ž์ด๋‹ค.
  • @WebMvcTest
    • ์—ฌ๋Ÿฌ Spring-boot ์–ด๋…ธํ…Œ์ด์…˜ ์ค‘ Web ์–ด๋…ธํ…Œ์ด์…˜์ด๋‹ค.
    • ์„ ์–ธํ•  ๊ฒฝ์šฐ @Controller, @ControllerAdvice๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • @Autowired
    • Spring์ด ๊ด€๋ฆฌํ•˜๋Š” Bean์„ ์ฃผ์ž…๋ฐ›๋Š”๋‹ค.
  • private MockMvc mvc
    • Spring MVC ํ…Œ์ŠคํŠธ์˜ ์‹œ์ž‘์ ์ด๋‹ค.
    • ์ด ํด๋ž˜์Šค๋ฅผ ํ†ตํ•ด HTTP GET, POST๋“ฑ API ํ…Œ์ŠคํŠธ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • mvc.perform(get("/hello"))
    • MockMvc๋ฅผ ํ†ตํ•ด /hello ์ฃผ์†Œ๋กœ HTTP GET ์š”์ฒญ์„ ํ•œ๋‹ค.
  • .andExpect(status().isOk())
    • mvc.perform์˜ ๊ฒฐ๊ณผ๋ฅผ ๊ฒ€์ฆํ•œ๋‹ค.
    • HTTP Header์˜ Status๋ฅผ ๊ฒ€์ฆํ•œ๋‹ค.
  • .andExpect(content().string(hello))
    • mvc.perform์˜ ๊ฒฐ๊ณผ๋ฅผ ๊ฒ€์ฆํ•œ๋‹ค.
    • ์‘๋‹ต ๋ณธ๋ฌธ์˜ ๋‚ด์šฉ์„ ๊ฒ€์ฆํ•œ๋‹ค.

4. Test

๊ฐ method๋ณ„๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•ด ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
ํ•„์ž๋Š” VSCode๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๊ณ , Java Extension Pack์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์‚ฌ์šฉํ•œ๋‹ค.
1. Test ์‹คํ–‰
Run Test๋ฅผ ๋ˆ„๋ฅด๋ฉด unit test๋ฅผ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

2. ๊ฒฐ๊ณผ ํ™•์ธ
๋””๋ฒ„ํฌ ์ฝ˜์†”์„ ๋ณด์ž.
was๋ฅผ ํ•„์š”๋กœํ•˜๋Š” Controller Test์ด๊ธฐ์— Spring-boot application์ด ์‹คํ–‰๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
Test ๊ฒฐ๊ณผ๋Š” VSCode ์ขŒ์ธก ํ”Œ๋ผ์Šคํฌ ์•„์ด์ฝ˜์„ ํด๋ฆญํ•˜์—ฌ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

5. Start

# ๋นŒ๋“œ
./gradlew build
# Spring-boot ์‹คํ–‰
java -jar ./build/lib/*.jar

# ํ…Œ์ŠคํŠธ
curl localhost:8080/hello   # hello

๋ชจ๋“  ์†Œ์Šค๋Š” ๊นƒํ—ˆ๋ธŒ์— ์˜ฌ๋ ค๋†“์•˜๋‹ค.
์ฐธ๊ณ ์„œ์ : ์Šคํ”„๋ง๋ถ€ํŠธ์™€ AWS๋กœ ํ˜ผ์ž ๊ตฌํ˜„ํ•˜๋Š” ์›น ์„œ๋น„์Šค

0๊ฐœ์˜ ๋Œ“๊ธ€