Spring test

์Šคํ”„๋ง ๋ถ€ํŠธ์—์„œ๋Š” ๊ธฐ๋ณธ์ ์ธ ํ…Œ์ŠคํŠธ ์Šคํƒ€ํ„ฐ๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ์Šคํƒ€ํ„ฐ์— ์›ฌ๋งŒํ•œ ํ…Œ์ŠคํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์„ ๋ญ‰์ณ๋†“์•„ ํŽธ๋ฆฌํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

  • spring-boot-test

  • spring-boot-test-autoconfigure

์œ„ ๋‘๊ฐœ ๋ชจ๋“ˆ์ด ํ…Œ์ŠคํŠธ ๊ด€๋ จ ์ž๋™ ์„ค์ • ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๊ณ , ์ผ๋ฐ˜์ ์œผ๋กœ spring-boot-starter-test๋กœ ๋‘ ๋ชจ๋“ˆ์„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•œ๋‹ค.

dependencies {
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

๋‹จ์œ„ ํ…Œ์ŠคํŠธ(JUnit)

Spring Boot์—์„œ JUnit5๋ฅผ ์ด์šฉํ•ด ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด๊ธฐ ์ „์— ๊ธฐ๋ณธ์ ์ธ ๋‚ด์šฉ์— ๋Œ€ํ•ด์„œ ๋‹ค๋ฃจ๊ณ  ๋„˜์–ด๊ฐˆ ๊ฒƒ์ด๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ(Unit Test) ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ 5๊ฐ€์ง€ ์›์น™์„ ๊ฐ•์กฐํ•œ๋‹ค.

  • Fast : ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ์ผ์€ ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋ฉด ์•ˆ๋œ๋‹ค.

  • Independent : ๋…๋ฆฝ์ ์œผ๋กœ ์‹คํ–‰์ด ๋˜์–ด์•ผํ•œ๋‹ค.

  • Repeatable : ๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•ด์•ผํ•œ๋‹ค.

  • Self Validation : ๋ฉ”๋‰ด์–ผ ์—†์ด ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋งŒ ์‹คํ–‰ํ•ด๋„ ์„ฑ๊ณต, ์‹คํŒจ ์—ฌ๋ถ€๋ฅผ ์•Œ ์ˆ˜ ์žˆ์–ด์•ผํ•œ๋‹ค.

  • Timely : ๋ฐ”๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ด์•ผํ•œ๋‹ค.

Junit

Junit์€ Java์˜ ๋‹จ์œ„ ํ…Œ์ŠคํŒ… ๋„๊ตฌ์ด๋‹ค.

  • ๋‹จ์œ„ ํ…Œ์ŠคํŠธ Framework์ค‘ ํ•˜๋‚˜

  • ๋‹จ์ •๋ฌธ์œผ๋กœ Test Case ์ˆ˜ํ–‰๊ฒฐ๊ณผ๋ฅผ ํŒ๋ณ„ํ•œ๋‹ค.

  • Annotation์œผ๋กœ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•˜๋‹ค.

Dependencies

spring boot 2.2.0 ์ดํ›„ ๋ฒ„์ „์—์„œ๋Š” Junit5๊ฐ€ ๊ธฐ๋ณธ์œผ๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ๋‹ค. Junit5๋Š” Java8 ๋ถ€ํ„ฐ ์ง€์›ํ•˜๋ฉฐ, ์ด์ „ ๋ฒ„์ „์œผ๋กœ ์ž‘์„ฑ๋œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์—ฌ๋„ ์ปดํŒŒ์ผ์ด ์ง€์›๋œ๋‹ค.

SpringBoot 2.2.0 ์ด์ „ ๋ฒ„์ „์—์„œ junit5 ์„ค์ •

  • maven

  • gradle

Test ๋‹จ์œ„

์„ค๋ช…
Bean

@SpringBootTest

ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ, ์ „์ฒด

Bean ์ „์ฒด

@WebMvcTest

๋‹จ์œ„ ํ…Œ์ŠคํŠธ, Mvc ํ…Œ์ŠคํŠธ

MVC ๊ด€๋ จ๋œ Bean

@DataJpaTest

๋‹จ์œ„ ํ…Œ์ŠคํŠธ, Jpa ํ…Œ์ŠคํŠธ

JPA ๊ด€๋ จ Bean

@RestClientTest

๋‹จ์œ„ ํ…Œ์ŠคํŠธ, Rest API ํ…Œ์ŠคํŠธ

์ผ๋ถ€ Bean

@JsonTest

๋‹จ์œ„ ํ…Œ์ŠคํŠธ, Json ํ…Œ์ŠคํŠธ

์ผ๋ถ€ Bean

  • @SpringBootTest ๋Š” ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋ณธ์ ์ธ Spring Boot Test ์–ด๋…ธํ…Œ์ด์…˜์ด๋‹ค. ์—ฌ๋Ÿฌ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ํ•˜๋‚˜์˜ ํ†ตํ•ฉ๋œ ํ…Œ์ŠคํŠธ๋กœ ์ˆ˜ํ–‰ํ•  ๋•Œ ์ ํ•ฉํ•˜๋‹ค.

    • @SpringBootApplication ์ด ๋ถ™์€ ์–ด๋…ธํ…Œ์ด์…˜์„ ์ฐพ์•„ context๋ฅผ ์ฐพ๋Š”๋‹ค.

    • ์‹ค์ œ ๊ตฌ๋™๋˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ๋˜‘๊ฐ™์ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปจํ…์ŠคํŠธ๋ฅผ ๋กœ๋“œํ•ด ํ…Œ์ŠคํŠธํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ•˜๊ณ  ์‹ถ์€ ํ…Œ์ŠคํŠธ๋ฅผ ๋ชจ๋‘ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

    • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์„ค์ •๋œ ๋นˆ์„ ๋ชจ๋‘ ๋กœ๋“œํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ทœ๋ชจ๊ฐ€ ํด์ˆ˜๋ก ๋А๋ ค์ง„๋‹ค.

    • properties : ํ…Œ์ŠคํŠธ ์‹คํ–‰๋˜๊ธฐ์ „ {key,value} ํ˜•์‹์œผ๋กœ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

    • value : ํ…Œ์ŠคํŠธ ์‹คํ–‰ ์ „ ์ ์šฉํ•  ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ๋‹ค.

    • classes : ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปจํ…์ŠคํŠธ์— ๋กœ๋“œํ•  ํด๋ž˜์Šค๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ณ„๋„๋กœ ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด, @SpringBootApplication or @SpringBootConfiguration ์„ ์ฐพ์•„์„œ ๋กœ๋“œํ•œ๋‹ค.

  • @ExtendWith ๋Š” ํ™•์žฅ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•œ๋‹ค.

    • JUnit5์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ์˜ ์ƒ๋‹น์ˆ˜๊ฐ€ ์ด ๊ธฐ๋Šฅ์œผ๋กœ ์ง€์›๋˜๊ณ  ์žˆ๋‹ค.

    • ์‹ค์ œ ๊ธฐ๋Šฅ์ด ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด์„œ ์‹คํ–‰๋œ๋‹ค.

    • JUnit4์—์„œ RunWith์™€ ์œ ์‚ฌํ•˜๋‹ค.

  • @ActiveProfiles ๋Š” ์›ํ•˜๋Š” ํ”„๋กœํŒŒ์ผ ํ™˜๊ฒฝ ๊ฐ’์„ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ๋‹ค.

  • @Transactional : ํ…Œ์ŠคํŠธ๋ฅผ ๋งˆ์น˜๊ณ  ๋‚˜์„œ ์ˆ˜์ •๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋กค๋ฐฑ๋œ๋‹ค.

Mock ๊ฐ์ฒด

ํ…Œ์ŠคํŠธ์‹œ ๋ชจ๋“  ๊ฐ€๋ณ€์ ์ธ ์˜์—ญ(์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„, ๋ฉ”์‹œ์ง• ๋ฏธ๋“ค์›จ์–ด, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค)์€ ๊ด€๋ฆฌํ•˜๊ธฐ ์–ด๋ ค์šฐ๋ฉฐ, ์ƒํ˜ธ์ž‘์šฉ์‹œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ์˜ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚œ๋‹ค.

๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ํ…Œ์ŠคํŠธํ•  ๋ชฉ์ ์ด๋ผ๋ฉฐ, ํ•ด๋‹น ๋กœ์ง์ด ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ๋‹ค์–‘ํ•œ ์˜์กด์„ฑ์„ ๋ชจ๋‘ ํ…Œ์ŠคํŠธํ•  ํ•„์š”๋Š” ์—†๋‹ค. Mock ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์—์„œ ํ•„์š”ํ•œ ์˜์กด์„ฑ์„ ๋Œ€์ฒดํ•˜๊ณ , ์™ธ๋ถ€ ์˜์กด์„ฑ์˜ ์˜ํ–ฅ ์—†์ด ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

Stub์€ ํ…Œ์ŠคํŠธ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ํ•˜๋“œ์ฝ”๋”ฉ๋œ ๊ตฌํ˜„์ฒด์ด๋‹ค. (Stub์€ Mock ๊ฐ์ฒด๊ฐ€ ์•„๋‹˜)

Mockito

Mockito๋Š” ํ”„๋ก์‹œ ๊ธฐ๋ฐ˜์˜ Mock๊ฐ์ฒด ํ”„๋ ˆ์ž„์›Œํฌ๋กœ ํ‘œํ˜„๊ตฌ๋ฌธ๊ณผ ๋งŽ์€ ์œ ์—ฐ์„ฑ์„ ์ œ๊ณตํ•œ๋‹ค. Mockito๋ฅผ ์‚ฌ์šฉํ•ด ํ™•์ธ์ด ํ•„์š”ํ•œ ๋™์ž‘์„ ๋ชจํ‚นํ•ด ์ค‘์š”ํ•œ ๋™์ž‘๋งŒ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ๋‹ค.

MockMvc Test

MockMvc ๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„œ ์š”์ฒญ๊ณผ ์‘๋‹ต์„ ์˜๋ฏธํ•˜๋Š” ๊ฐ์ฒด๋กœ์„œ ์›น์—์„œ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ํž˜๋“  Controller ํ…Œ์ŠคํŠธ๋ฅผ ์šฉ์ดํ•˜๊ฒŒ ํ•ด์ค€๋‹ค. ๋˜ํ•œ ์‹œํ๋ฆฌํ‹ฐ ํ˜น์€ ํ•„ํ„ฐ๊นŒ์ง€ ์ž๋™์œผ๋กœ ํ…Œ์ŠคํŠธํ•ด ์ˆ˜๋™์œผ๋กœ ์ถ”๊ฐ€/์‚ญ์ œ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

@WebMvcTest๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • Book.java

  • Service

  • Controller

  • test

  • @WebMvcTest(BookController.class) : ํ…Œ์ŠคํŠธํ•  ์ปจํŠธ๋กค๋Ÿฌ๋ช…์„ ๋ช…์‹œํ•ด์ค€๋‹ค.

  • ์—ฌ๊ธฐ์„œ @Service์€ @WebMvcTest์˜ ์ ์šฉ ๋Œ€์ƒ์ด ์•„๋‹ˆ๋‹ค. BookService ์ธํ„ฐํŽ˜์ด์Šฌ๋ฅด ๊ตฌํ˜„ํ•œ ๊ตฌํ˜„์ฒด๋Š” ์—†์ง€๋งŒ, @MockBean์„ ์ ๊ทน์ ์œผ๋กœ ํ™œ์šฉํ•ด ์ปจํŠธ๋กค๋Ÿฌ ๋‚ด๋ถ€์˜ ์˜์กด์„ฑ ์š”์†Œ๋ฅผ ๊ฐ์ž ๊ฐ์ฒด๋กœ ๋Œ€์ฒด ํ–ˆ๋‹ค. MockBean์€ ์‹ค์ œ ๊ฐ์ฒด๋Š” ์•„๋‹ˆ์ง€๋งŒ ์‹ค์ œ ๊ฐ์ฒด์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

    • given(bookService.getBookList()).willReturn(Collections.singletonList(book)); : ๊ฐ€์งœ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด given()์„ ์‚ฌ์šฉํ•ด ๋ฉ”์„œ๋“œ ์‹คํ–‰์— ๋Œ€ํ•œ ๋ฐ˜ํ™˜๊ฐ’์„ ๋ฏธ๋ฆฌ ์„ค์ •ํ–ˆ๋‹ค.

  • ๊ทธํ›„ andExpect()๋กœ ์˜ˆ์ƒ ๊ฐ’์ด ๋‚˜์˜ค๋Š”์ง€์— ๋Œ€ํ•ด์„œ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ–ˆ๋‹ค.

๋งŒ์•ฝ ๊ธฐ๋ณธ์„ค์ •๋งŒ ํ•„์š”ํ•˜๋‹ค๋ฉด @AutoConfigureMockMvc ์œผ๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ AutoConfig๋กœ ์„ค์ •์„ ํ•˜๋ฉด Customํ•˜๊ธฐ ์–ด๋ ค์›Œ์ง„๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ๋Š” MockMvcBuilders๋ฅผ ํ™œ์šฉํ•ด MockMvc ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ด์ฃผ์—ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๊ณตํ†ต ์ถ”์ƒํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด์ œ ์ถ”์ƒ ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์•„ Controller ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • @Test : ํ…Œ์ŠคํŠธ ๋Œ€์ƒ์„ ์ง€์ •

  • @Order : ํ…Œ์ŠคํŠธ ์ˆ˜ํ–‰ ์ˆœ์„œ ์ง€์ •

  • @TestMethodOrder(OrderAnnotation.class) : OrderAnnotation ๊ธฐ์ค€์œผ๋กœ ํ…Œ์ŠคํŠธ ์ˆ˜ํ–‰

์ฐธ์กฐ

Last updated

Was this helpful?