RestAssured
์ํฉ
ํ ์น ์๋น์ค API ํ๋ก์ ํธ ์งํํ๋ฉด์ Spring MockMvc๋ฅผ ์ฌ์ฉํ์ฌ ํ ์คํธ๋ฅผ ์งํํด์์ต๋๋ค.
MockMvc์ ํ๊ณ
MockMvc๋ Spring MVC์ ์ปจํธ๋กค๋ฌ ํ ์คํธ์ ํนํ๋์ด ์์ง๋ง, ์ค์ HTTP ์์ฒญ๊ณผ ์๋ต์ ํ๋ฆ์ ์์ ํ ๋ชจ๋ฐฉํ์ง๋ ๋ชปํฉ๋๋ค.
๋ณต์กํ ์ค์ ๊ณผ ์๋์ ์ผ๋ก ๋ฎ์ ๊ฐ๋ ์ฑ์ผ๋ก ์ธํด ํ ์คํธ ์ฝ๋์ ์ ์ง ๊ด๋ฆฌ๊ฐ ์ด๋ ต์ต๋๋ค.
์์ ์ฝ๋
@Sql(statements = "insert into organization (title) values ('eojjeogojeojjeogo')")
@DisplayName("๋ง์ผ ์คํค ์์ ์์ฒญํ๋ฉด 200 ์ฝ๋๋ฅผ ์๋ตํ๋ค")
@Test
void updateMilestone() throws Exception {
// given
long milestoneId = milestoneService.create(ORGANIZATION_TITLE, createMileStoneRequest);
MilestoneRequest changedMilestoneRequest = new MilestoneRequest(TEST_TITLE, TEST_DESCRIPTION,
TEST_DUE_DATE);
// when
mockMvc.perform(patch("/api/" + ORGANIZATION_TITLE + "/milestones/" + milestoneId)
.content(objectMapper.writeValueAsString(changedMilestoneRequest))
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
)
// then
.andDo(print())
.andExpect(status().isOk());
}
๋ง์ฝ์์ milestoneService์ create์ ๋ฉ์๋๊ฐ ๋ณ๊ฒฝ์ ํ๋ฉด ํ ์คํธ์ฝ๋๋ ๋์ํ๊ฒ ๋ณ๊ฒฝํด์ผ ํ๋ค.
ํด๊ฒฐ ๋ฐฉ๋ฒ
MockMvc ๋์ RestAssured์ Cucumber๋ฅผ ์ฌ์ฉํ์ฌ BDD ๋ฐฉ์์ผ๋ก ๊ฐ์ ํ๋ ค๊ณ ๊ฒํ ํ์ต๋๋ค.
RestAssured์ Cucumber์ ๋น๊ต
RestAssured์ ์ฅ์
์ค์ HTTP ํ ์คํธ: RestAssured๋ ์ค์ HTTP ์์ฒญ๊ณผ ์๋ต์ ํ ์คํธํ์ฌ ์ค์ ํ๊ฒฝ์ ๋ ๊ฐ๊น์ด ํ ์คํธ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.
๊ฐ๊ฒฐํ๊ณ ๋ช ํํ API: API ํ ์คํธ์ ์ต์ ํ๋ ๊ตฌ๋ฌธ์ ์ ๊ณตํ์ฌ ํ ์คํธ ์ฝ๋์ ๊ฐ๋ ์ฑ๊ณผ ์ ์ง ๊ด๋ฆฌ๋ฅผ ํฅ์์ํต๋๋ค.
API ํ ์คํธ์ ํนํ: ๋ณต์กํ API ์์ฒญ ๋ฐ ๋ฐ์ดํฐ ํฌ๋งท์ ์ฝ๊ฒ ์ฒ๋ฆฌํ ์ ์์ด API ํ ์คํธ์ ๋งค์ฐ ์ ํฉํฉ๋๋ค.
given().
config(RestAssured.config().xmlConfig(xmlConfig().declareNamespace("test", "http://localhost/"))).
when().
get("/namespace-example").
then().
body("foo.bar.text()", equalTo("sudo make me a sandwich!")).
body(":foo.:bar.text()", equalTo("sudo ")).
body("foo.test:bar.text()", equalTo("make me a sandwich!"));
Cucumber์ ์ฅ์
BDD ์ ๊ทผ๋ฒ: Cucumber๋ ์์ฐ ์ธ์ด๋ก ํ ์คํธ ์๋๋ฆฌ์ค๋ฅผ ์์ฑํ์ฌ, ๋น๊ธฐ์ ์ ์ดํด๊ด๊ณ์๋ ํ ์คํธ ๊ณผ์ ์ ์ฝ๊ฒ ์ดํดํ๊ณ ์ฐธ์ฌํ ์ ์์ต๋๋ค.
ํ ๋ด ์ปค๋ฎค๋์ผ์ด์ ๊ฐํ: BDD ์ ๊ทผ๋ฒ์ ๊ฐ๋ฐ์, ํ ์คํฐ, ๋น์ฆ๋์ค ์ดํด๊ด๊ณ์ ๊ฐ์ ๋ช ํํ ์ปค๋ฎค๋์ผ์ด์ ์ ์ด์งํฉ๋๋ค.
์ฌ์ฉ์ ์ค์ฌ์ ํ ์คํธ: ์ฌ์ฉ์์ ๊ฒฝํ๊ณผ ์๊ตฌ์ฌํญ์ ๊ธฐ๋ฐํ์ฌ ํ ์คํธ๋ฅผ ์ค๊ณํ๊ณ ๊ตฌํํ ์ ์์ต๋๋ค.
Scenario: Breaker guesses a word
Given the Maker has chosen a word
When the Breaker makes a guess
Then the Maker is asked to score
๋ด๊ฐ ์ ํํ ๋ฐฉ๋ฒ๊ณผ ์ด์
RestAssured๋ฅผ ์ฌ์ฉํ์ฌ ์ค์ HTTP ํ ์คํธ๋ฅผ ํ ์คํธ ํ ์ ์๊ณ ๊ฐ๊ฒฐํ๊ณ ๋ช ํํ API๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ๋ ์ฑ์ ๋์ผ ์ ์๊ณ ํ ์คํธ ์ฝ๋๋ฅผ ์ ์ง ๋ณด์๊ฐ ์ฝ๋ค๊ณ ์๊ฐํ์ฌ ์ ํํ์ต๋๋ค.
๊ฒฐ๊ณผ
ํ ์คํธ Step๋ฅผ ํ๊ธ ๋ฉ์๋๋ฅผ ํตํฉํ๊ณ ํ ์คํธ์ ๊ฐ๋ ์ฑ๋ฅด ํฅ์๋์๊ณ ๋น์ง๋์ค ๋ก์ง์ ๋ณ๊ฒฝ ๋ฐ๋ผ ๋ณ๊ฒฝ์ด ์ ์ด์ก์ต๋๋ค.
@DisplayName("๋ด ๊ด์ฌ์ํ์ ๋ด์ ํ, ํด๋น ๊ด์ฌ์ํ ์ญ์ ")
@Test
void shouldRemoveProductToInterestedProductsList() {
์ถ๋ ฅ_ํ๋_์ถ๊ฐ("member_removeLikeProduct", spec);
// given
var id = ์ํ์_๋ฑ๋กํ๋ค(ayaanAccessToken, 1).jsonPath().getString("id");
๊ด์ฌ์ํ์_๋ด๋๋ค(id, albertAccessToken);
// when
var response = ๊ด์ฌ์ํ์_์ ๊ฑฐํ๋ค(id, albertAccessToken, spec);
// then
๊ด์ฌ์ํ์_๋ด์_์๋ต_๊ฒ์ฆ(response);
}
Last updated
Was this helpful?