[springboot-webserivce] GET API test ์ฝ๋ ์์ฑ
Updated:
[2020.12.28] ๋ถํฐ ์คํ๋ง ๋ถํธ์ AWS๋ก ํผ์ ๊ตฌํํ๋ ์น ์๋น์ค ์ฑ ์ ํตํด ์คํ๋ง ๊ณต๋ถ๋ฅผ ์์ํ๋ค.
๊ณต๋ถํ ๋ด์ฉ์ ๊ธ๋ก ์ ๋ฆฌํ๋ ค๊ณ ํ๋ค.
๊ทธ๋์ผ ๋์ค์ ๋ค์ ์ฐพ์๋ณด๋ฉฐ ๊ณต๋ถ ํ ์ ์์ํ ๋๊น !!
๐ TDD
TDD ๋ ํ ์คํธ๊ฐ ์ฃผ๋ํ๋ ๊ฐ๋ฐ ์ ์๋ฏธํ๋ค.
๋จผ์ ๋ฌด์กฐ๊ฑด ์คํจํ๋ ๊ฒฝ์ฐ์ ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํ๊ณ ๋ค์์ผ๋ก ํ ์คํธ๋ฅผ ํต๊ณผํ๋ ํ๋ก๋์ ์ฝ๋๋ฅผ ์์ฑํ๋ค.
ํ ์คํธ๊ฐ ํต๊ณผ๋๋ฉด ํด๋น ํ๋ก๋์ ์ฝ๋๋ฅผ ๋ฆฌํฉํ ๋ง ํ๋ค.
์ด ์ฌ์ดํด์ TDD ๋ผ๊ณ ํ๋๋ฐ ๋จผ์ TDD ์ ์ฒซ ๋ฒ์งธ ๋จ๊ณ์ธ ๊ธฐ๋ฅ ๋จ์์ ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํ๋ ค๊ณ ํ๋ค.
ํ ์คํธ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ ์ด์ ๋ก ๊ฐ๋ฐ์ ์์ด ํ์์ด๋ค.
- ๊ฐ๋ฐ๋จ๊ณ ์ด๊ธฐ์ ๋ฌธ์ ๋ฅผ ๋ฐ๊ฒฌํ๊ฒ ๋์์ค๋ค.
- ๋ฆฌํฉํ ๋ง์ ํ๊ฑฐ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ๊ทธ๋ ์ด๋ ๋ฑ์์ ๊ธฐ์กด ๊ธฐ๋ฅ์ด ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋์ง ํ์ธํ ์ ์๋ค.
- ๊ธฐ๋ฅ์ ๋ํ ๋ถํ์ค์ฑ์ ๊ฐ์ ์ํจ๋ค.
์ ์์ ๊ฒฝํ์ ์๋ก ๋ค์๋ฉด ์ ์๋ ๋จ์ ํ ์คํธ๋ฅผ ๋ฐฐ์ฐ๊ธฐ ์ ์ ๊ฐ๋ฐ ๊ณผ์ ์ ์ด๋ฌํ๋ค.
- ์ฝ๋๋ฅผ ์์ฑ
- ํ๋ก๊ทธ๋จ์ ์คํ
- Postman ๊ณผ ๊ฐ์ API ํ ์คํธ ๋๊ตฌ๋ก HTTP ์์ฒญ
- System.out.println() ์ ํตํด ๋์ผ๋ก ๊ฒ์ฆ
- ์ฝ๋ ์์
์ด๋ฐ ๊ณผ์ ์ผ๋ก ๊ฐ๋ฐ์ ํด์ 3, 4, 5 ๋ฒ ๊ณผ์ ์ ๊ฑฐ์น ๋ ๋ง๋ค ํฐ์บฃ์ ๊ป๋ค ์ผ์ผํ๋ ๋ถํธํจ์ด ์์๋ค๊ณ ํ๋ค.
ํ์ง๋ง ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํด์ ์คํํ๋ค๋ฉด ๊ฒ์ฆ๋ ์๋์ผ๋ก ํด์ค ๋ฟ๋ง ์๋๋ผ ์ด๋ฌํ ๋ถํธํจ ๊น์ง ์์ด์ง๋ค.
๐ฅฎ JUnit
์์ ๋งํ ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑ์ ๋์์ฃผ๋ ํ๋ ์์ํฌ๋ก xUnit ์ด ์๋ค.
x ๋ ๊ฐ๋ฐ ํ๊ฒฝ์ ๋ฐ๋ผ ๋ฐ๋๊ฒ ๋๋๋ฐ ๋๋ Java ๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ JUnit ์ ์ฌ์ฉํ๋ค.
์ต์ ๋ฒ์ ์ ๋ฒ์ 5๊น์ง ์์ง๋ง ๋๋ถ๋ถ์ ํ์ฌ์์ ๋ฒ์ 4๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ์ค์ต์์๋ ๋ฒ์ 4๋ฅผ ์ฌ์ฉํ๋ค.
๐ง Main ํด๋์ค, GET API ์์ฑ
ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ ์ํด ์ฐ์ Main ํด๋์ค์ GET API ๋ฅผ ๋ง๋ค๋ ค๊ณ ํ๋ค.
src/main/java ํด๋์ ์น ์ฌ์ดํธ ์ฃผ์ ๋ช ์ ์ญ์์ ์ด๋ฆ์ผ๋ก ๊ฐ์ง๋ ํจํค์ง๋ฅผ ๋ง๋ ๋ค.
๊ทธ๋ฆฌ๊ณ ๊ทธ ํจํค์ง์ Application ํด๋์ค๋ฅผ ๋ง๋ ๋ค.
์ด ํด๋์ค๊ฐ ์์ผ๋ก ๋ง๋ค ํ๋ก์ ํธ์ ๋ฉ์ธ ํด๋์ค๊ฐ ๋๋ค.
package com.boks.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
// ์คํ๋ง ๋ถํธ์ ์๋ ์ค์ , ์คํ๋ง Bean ์ฝ๊ธฐ์ ์์ฑ ๋ชจ๋ ์๋ ์ค์
// ์ด Annotation ๋ถํฐ ์ค์ ์ ์ฝ๊ธฐ ๋๋ฌธ์ ์ด ํด๋์ค๋ ํญ์ ํ๋ก์ ํธ ์ต์๋จ์ ์์ด์ผ ํจ
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
SpringApplication.run ๋ฉ์๋๋ฅผ ์คํ์ํค๋ฉด ๋ด์ฅ WAS ๊ฐ ์คํ๋๋ค.
๋ค์์ผ๋ก ๋ฐฉ๊ธ ๋ง๋ค์๋ ํจํค์ง์ ํ์ ํจํค์ง๋ก controller ํด๋์ค๋ค์ ๋ด์ web ํจํค์ง๋ฅผ ์์ฑํ๋ค.
web ํจํค์ง์ 127.0.0.1:8080/hello ์ฃผ์๋ก GET ์์ฒญ์ ๋ณด๋ด๋ฉด hello ๋ฅผ ๋ฐํํ๋ API ๋ฅผ ๋ง๋ค ๊ฒ์ด๋ค.
package com.boks.springboot.web;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController // ์ปจํธ๋กค๋ฌ๋ฅผ JSON์ ๋ฐํํ๋ ์ปจํธ๋กค๋ฌ๋ก ๋ง๋ค์ด ์ค.
public class HelloController {
@GetMapping("/hello") // GET ์์ฒญ์ ๋ฐ์ ์ ์๋ API๋ฅผ ๋ง๋ค์ด ์ค.
public String hello() {
return "hello";
}
}
์ฌ๊ธฐ๊น์ง๊ฐ Main ํด๋์ค์ GET API ๋ฅผ ์์ฑํ๋ ๊ณผ์ ์ด์๋ค.
ํ ์คํธ ์ฝ๋๊ฐ ์๋ค๋ฉด ์ง๊ธ ๋ง๋ API ๋ฅผ ํ ์คํธ ํ๊ธฐ ์ํด ๋ฉ์ธ ํด๋์ค๋ฅผ ํตํด WAS ๋ฅผ ์คํ ์ํจ ๋ค
127.0.0.1:8080/hello ์ฃผ์๋ก ์ง์ ์ ์ ํด ๋์ผ๋ก ํ์ธํด์ผ ํ๋ค.
ํ์ง๋ง JUnit ์ ์ด์ฉํด ํ ์คํธ ์ฝ๋๋ฅผ ๋ง๋ ๋ค๋ฉด WAS ๋ฅผ ์คํ ์ํฌ ํ์์์ด ๊ฒ์ฆ์ ํ ์ ์๋ค.
๐ง JUnit์ ํตํ ํ ์คํธ์ฝ๋ ์์ฑ
์์ ๋ง๋ค์๋ ํจํค์ง๋ฅผ ๊ทธ๋๋ก test ์ ๋ง๋ค์ด ์ฃผ์.
์ผ๋ฐ์ ์ผ๋ก ํ ์คํธ ํด๋์ค๋ ํด๋น ํด๋์ค ์ด๋ฆ ๋ค์ Test ๋ฅผ ๋ถ์ธ๋ค๊ณ ํ๋ค.
๋ฐ๋ผ์ HelloControllerTest ํด๋์ค๋ฅผ ๋ง๋ค์.
package com.boks.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) // ์คํ๋ง ๋ถํธ ํ
์คํธ์ JUnit ์ฌ์ด์ ์ฐ๊ฒฐ์ ์ญํ
@WebMvcTest(controllers = HelloController.class) // ์ฌ๋ฌ ์คํ๋ง ํ
์คํธ ์ด๋
ธํ
์ด์
์ค web์ ์ง์ค
public class HelloControllerTest {
@Autowired // ์คํ๋ง์ด ๊ด๋ฆฌํ๋ bean์ ์ฃผ์
private MockMvc mvc; // ์น API๋ฅผ ํ
์คํธ ํ๋ ๊ฒฝ์ฐ ์ฌ์ฉ, ํ
์คํธ์ ์์์
@Test
public void returnHello() throws Exception {
String hello = "hello";
mvc.perform(get("/hello")) // MockMvc๋ฅผ ํตํด /hello ์ฃผ์๋ก GET ์์ฒญ
.andExpect(status().isOk()) // ์ด ์์ฒญ์ ์ํ๋ฅผ ๊ฒ์ฆ, ์ด ๊ฒฝ์ฐ OK ์ฆ 200 ์ธ์ง ํ์ธ
.andExpect(content().string(hello)); // GET์ ํตํด ๋ฐ์ ๊ฐ์ด hello ์ธ์ง ํ์ธ
}
}
์ด๋ ธํ ์ด์ ์ด ๋ง์์ ๋ณต์กํด ๋ณด์ผ ์ ์์ง๋ง ํฐ ํ์ ๋ณด์๋ฉด
MockMvc ์ธ์คํด์ค๋ฅผ ๊ฐ์ง๋ mvc ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด perform ๋ฉ์๋๋ฅผ ํตํด /hello ์ฃผ์๋ก GET ์ ์์ฒญ ํ ๋ค
์์ฒญ์ ์ํ๋ฅผ status().isOk ๋ก ๊ฒ์ฆ์ ํ๊ณ GET ์ ํตํด ๋ฐ์ ๊ฐ์ด hello ์ธ์ง ๊ฒ์ฌํ๋ ์ฝ๋์ด๋ค.
returnHello ๋ฉ์๋๋ฅผ ๋์ํ๊ฒ ๋๋ฉด ํ ์คํธ๋ฅผ ์์ํ๋๋ฐ ํ ์คํธ๊ฐ ์ฑ๊ณต์ ์ผ๋ก ๋๋๊ฒ ๋๋ฉด
ํ ์คํธ ํต๊ณผ๋ฅผ ์ ์ ์๋ค.
status ๊ฐ Ok, 200 ์ด ์๋๊ฑฐ๋ GET ์ ํตํด ๋ฐ์ ๊ฐ์ด hello ๊ฐ ์๋๋ผ๋ฉด Tests Failed ์ด ๋๋ค.
์ด ๊ฒฐ๊ณผ๋ฅผ ๋ชป๋ฏฟ๊ฒ ๋ค.. ์ถ์ผ๋ฉด ์ค์ ๋ก WAS ๋ฅผ ์คํ ์์ผ ์ง์ ํ์ธํด๋ ๋๋ค.
Application ํด๋์ค๋ฅผ ์คํ์ํจ ๋ค 127.0.0.1:8080/hello ๋ก ์ ์์ ํด๋ณด์.
ํฐ์บฃ์ด 8080 ํฌํธ๋ก ์คํ ๋์๋ค๋ ๋ฉ์์ง๋ ๋ณด์ธ๋ค.
hello ๊ฐ ์ ์ถ๋ ฅ ๋๋ ๊ฒ๋ ์ ์ ์๋ค.
ํ ์คํธ ์ฝ๋๋ก ํ ์คํธ ํ ์ ๋ง๋ก ๋ชป ๋ฏฟ๊ฒ ๋ค ํ๋ ๊ฒฝ์ฐ์๋ง ์ด๋ ๊ฒ ์ง์ ๋์ผ๋ก ํ์ธ ํ์.
์๋์ผ๋ก ํ์ธ ํ ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํ๋ ํ์๋ ์ ๋ ๊ธ์ง์ด๋ค.
Leave a comment