Java

[Mockito & JUnit] @Mock ๊ณผ @InjectMock

hyunki.Dev 2023. 3. 28. 00:25

๐Ÿ“Œ Mockito ๋ž€?

Mockito ๋Š” Junit5๋ฅผ ์ด์šฉํ•œ ๋‹จ์œ„ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ Mock์„ ์œ„ํ•ด ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” Framewor์ž…๋‹ˆ๋‹ค.

ํ…Œ์ŠคํŠธ ๋Œ€์—ญ(Test Double)์˜ ์ข…๋ฅ˜ ์ค‘ ๋ชจ์˜(Mock) ๊ฐ์ฒด๋ฅผ ํ•„์š”๋กœ ํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

โœ”๏ธ ํ…Œ์ŠคํŠธ ๋Œ€์—ญ(Test Double)

ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด ์‹ค์ œ ๊ฐ์ฒด๋ฅผ ๋Œ€์ฒดํ•˜๋Š” ๊ฒƒ์„ ๋งํ•ฉ๋‹ˆ๋‹ค.

 

โœ”๏ธ ๋ชจ์˜(Mock) ๊ฐ์ฒด

ํ˜ธ์ถœํ–ˆ์„ ๋•Œ ์‚ฌ์ „์— ์ •์˜๋œ ๋ช…์„ธ๋Œ€๋กœ์˜ ๊ฒฐ๊ณผ๋ฅผ ๋Œ๋ ค์ฃผ๋„๋ก ๋ฏธ๋ฆฌ ํ”„๋กœ๊ทธ๋žจ๋˜์–ด ์žˆ๋Š” ํ…Œ์ŠคํŠธ์šฉ ๊ฐ์ฒด.

 

Mockito ๊ธฐ๋ณธ ์‚ฌ์šฉ

//์˜์กด์„ฑ ์„ ์–ธ
testImplementation 'org.mockito:mockito-core:3.11.2'
testImplementation 'org.mockito:mockito-junit-jupiter:3.11.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'


//ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์—์„œ ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ์„ ์–ธ
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
}

 

Mock์ด๋ž€?

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

 

Mock ๊ฐ์ฒด ์‚ฌ์šฉ ํ•˜๋Š” ์ƒํ™ฉ

  • ํ…Œ์ŠคํŠธ ์ž‘์„ฑ์„ ์œ„ํ•œ ํ™˜๊ฒฝ ๊ตฌ์ถ•์ด ์–ด๋ ค์šด ๊ฒฝ์šฐ
  • ํ…Œ์ŠคํŠธ๊ฐ€ ํŠน์ • ๊ฒฝ์šฐ๋‚˜ ์ˆœ๊ฐ„์— ์˜์กด์ ์ธ ๊ฒฝ์šฐ

 

@Mock vs @InjectMocks

@Mock ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ Mock ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

@InjectMocks๋ผ๋Š” ์–ด๋…ธํ…Œ์ด์…˜์€ @Mock์ด ๋ถ™์€ Mock๊ฐ์ฒด๋ฅผ @InjectMocks๊ฐ€ ๋ถ™์€ ๊ฐ์ฒด์— ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

@Mock
private CouponHelper couponHelper;

@InjectMocks
private CouponInfoConfirmQueryService service;

 

JUnit ์–ด๋…ธํ…Œ์ด์…˜(annotation)

@SpringBootTest

ํ…Œ์ŠคํŠธ ํด๋ž˜์Šค์— SpringBootTest ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ํ•ด๋‹น ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด SpringBoot ์„œ๋ฒ„ ์ „์ฒด๋ฅผ ๋„์›๋‹ˆ๋‹ค.

  • ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ ˆ๋ฒจ ํ…Œ์ŠคํŠธ์‹œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
    • ์„œ๋ฒ„ ํ”„๋กœ๊ทธ๋žจ์˜ ํ™˜๊ฒฝ์„ค์ •, ํฌํŠธ, ์ฃผ์†Œ ๋“ฑ ์‹คํ–‰๋  ๋•Œ์˜ ๋Ÿฐํƒ€์ž„ ํ…Œ์ŠคํŠธ
  • ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ ์ˆ˜ํ–‰์‹œ ์ ํ•ฉํ•˜๋‹ˆ๋‹ค.
  • ํ…Œ์ŠคํŠธ ์‹คํ–‰์‹œ ์„œ๋ฒ„ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
  • ์‹ค์ œ ๊ตฌ๋™๋˜๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ๋˜‘๊ฐ™์€ Application Context๋ฅผ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.
  • ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋กœ๋“œ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ปค์งˆ ๊ฒฝ์šฐ ์†๋„๊ฐ€ ๋Š๋ ค์ง‘๋‹ˆ๋‹ค.

@WebMvcTest

  • MVC๋ฅผ ์œ„ํ•œ ํ…Œ์ŠคํŠธ
  • ๋Œ€ํ‘œ์ ์œผ๋กœ Controller ํ…Œ์ŠคํŠธ๋ฅผ ํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • Request, Response๋ฅผ ํ…Œ์ŠคํŠธ ํ•  ์ˆ˜ ์žˆ๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ž…๋‹ˆ๋‹ค.
  • Spring Security๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๋กœ๊ทธ์ธ, ๋กœ๊ทธ์•„์›ƒ, ์„ธ์…˜, ํ•„ํ„ฐ๋„ ์ž๋™์œผ๋กœ ํ…Œ์ŠคํŠธ ๋ฉ๋‹ˆ๋‹ค.
  • @SpringBootTest ์–ด๋…ธํ…Œ์ด์…˜์„ ์ด์šฉํ•ด๋„ @WebMvcTest์—์„œ ๊ฐ€๋Šฅํ•œ ํ…Œ์ŠคํŠธ๋Š” ๋ชจ๋‘ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปจํ…์ŠคํŠธ๋ฅผ ํ†ตํ•ด ์„œ๋ฒ„ ์•ฑ์„ ์ „๋ถ€ ๋กœ๋“œํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ, MVC๊ด€๋ จ ์–ด๋…ธํ…Œ์ด์…˜(@Controller, @ControllerAdvice, @JsonComponent)๊ณผ Filter, WebConfigurer, HandlerMethodArgumentResolver๋งŒ ๋กœ๋“œํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฌด๊ฒ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

 

@BeforeEach

  • ํ˜„์žฌ ํด๋ž˜์Šค์˜ ๊ฐ @Test, @RepeatedTest, @ParameterizedTest ๋˜๋Š” @TestFactory ๋ฉ”์†Œ๋“œ๋ณด๋‹ค ๋จผ์ € ๋ฉ”์†Œ๋“œ๊ฐ€ ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
  • ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ๋ณต์žกํ•ด์ง€๊ณ  ํ…Œ์ŠคํŠธ์— ์—ฌ๋Ÿฌ ์ดˆ๊ธฐํ™”๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋ฉด ์—ฌ๋Ÿฌ ๊ฐœ์˜ @BeforeEach ๋ฉ”์†Œ๋“œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  @BeforeEach
  public void beforeEach(WebApplicationContext ctx,
      RestDocumentationContextProvider restDocumentation) {
    this.mvc = MockMvcBuilders.webAppContextSetup(ctx)
        .addFilters(new SuccessResponseHeaderFilter()) //RestClient ์ˆ˜ํ–‰ ์ „ ๊ณตํ†ต์ ์ธ successFilter 
        .apply(documentationConfiguration(restDocumentation))
        .alwaysDo(print())
        .build();
  }

 

@AfterEach

  • ํ˜„์žฌ ํด๋ž˜์Šค์˜ ๊ฐ @Test, @RepeatedTest, @ParameterizedTest ๋˜๋Š” @TestFactory ๋ฉ”์†Œ๋“œ ์ดํ›„์— ๋ฉ”์†Œ๋“œ๊ฐ€ ์‹คํ–‰๋˜์–ด์•ผ ํ•จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
  • ํ…Œ์ŠคํŠธ๊ฐ€ ์‹คํŒจํ•ด๋„ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

 

 

์ฐธ๊ณ  : 

https://velog.io/@rara_kim/Mockito-JUnit-Mock%EC%9D%B4%EB%9E%80-%ED%85%8C%EC%8A%A4%ED%8A%B8%EC%8B%9C-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98

https://beststar-1.tistory.com/30

https://jaehoney.tistory.com/219