Mocking Framework - Mockito

Mockito๋Š” Java ๋‹จ์œ„ ํ…Œ์ŠคํŠธ(Unit Test) ์ž‘์„ฑ์„ ๋•๋Š” ๋ชจํ‚น(Mocking) ํ”„๋ ˆ์ž„์›Œํฌ๋กœ, ์‹ค์ œ ์˜์กด ๊ฐ์ฒด ๋Œ€์‹  ๊ฐ€์งœ ๊ฐ์ฒด(Mock Object)๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ œ์–ดํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.

  • ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ ๊ฒฉ๋ฆฌ: ์™ธ๋ถ€ ์š”์ธ(DB, ๋„คํŠธ์›Œํฌ, ๋‹ค๋ฅธ ํด๋ž˜์Šค์˜ ๋‚ด๋ถ€ ๋กœ์ง ๋“ฑ)์— ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๊ณ  ํ…Œ์ŠคํŠธ ๋Œ€์ƒ์˜ ๋กœ์ง์—๋งŒ ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›

  • ํ–‰๋™ ์ œ์–ด ๋ฐ ๊ฒ€์ฆ: ์›ํ•˜๋Š” ๋ชจ๋“  ์ƒํ™ฉ์„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜(Stubbing)ํ•˜๊ณ , ๋ฉ”์„œ๋“œ๊ฐ€ ์˜ˆ์ƒ๋Œ€๋กœ ํ˜ธ์ถœ๋˜์—ˆ๋Š”์ง€(Verification) ๊ฒ€์ฆํ•˜๋Š” ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณต

  • ๊ฐ€๋…์„ฑ ๋†’์€ ํ…Œ์ŠคํŠธ: BDD(Behavior-Driven Development) ์Šคํƒ€์ผ์„ ์ง€์›ํ•˜๋Š” ๋“ฑ, ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์˜ ์˜๋„๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›

1. Mock ๊ฐ์ฒด ์ƒ์„ฑ

์˜์กด์„ฑ์„ ๋Œ€์ฒดํ•  ๊ฐ€์งœ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์€ ํฌ๊ฒŒ ๋‘ ๊ฐ€์ง€๋‹ค.

Mockito.mock() ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ

๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ๋ฐฉ๋ฒ•์œผ๋กœ, mock() ์ •์  ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด Mock ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ์ƒ์„ฑํ•œ๋‹ค.

import static org.mockito.Mockito.mock;

class MemberServiceTest {

    MemberRepository mockMemberRepository = mock(MemberRepository.class);
}

@Mock ์–ด๋…ธํ…Œ์ด์…˜ ์‚ฌ์šฉ

JUnit 5 ํ™•์žฅ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์—ฌ ์• ๋…ธํ…Œ์ด์…˜ ๊ธฐ๋ฐ˜์œผ๋กœ Mock ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ฃผ์ž…ํ•œ๋‹ค.

  • @ExtendWith(MockitoExtension.class): ํ…Œ์ŠคํŠธ ํด๋ž˜์Šค์— Mockito ํ™•์žฅ ๊ธฐ๋Šฅ ํ™œ์„ฑํ™”

  • @Mock: ํ•ด๋‹น ํ•„๋“œ๋ฅผ Mock ๊ฐ์ฒด๋กœ ์ดˆ๊ธฐํ™”

  • @InjectMocks: ํ…Œ์ŠคํŠธ ๋Œ€์ƒ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ , @Mock ๋˜๋Š” @Spy๋กœ ์ƒ์„ฑ๋œ ์˜์กด ๊ฐ์ฒด๋ฅผ ์ž๋™์œผ๋กœ ์ฃผ์ž…

@Spy - ์‹ค์ œ ๊ฐ์ฒด ์ผ๋ถ€ Mocking

์‹ค์ œ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ ํŠน์ • ๋ฉ”์„œ๋“œ์˜ ํ–‰๋™๋งŒ ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

@MockBean - ์Šคํ”„๋ง ์ปจํ…์ŠคํŠธ ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ์šฉ

@Mock์ด ์ˆœ์ˆ˜ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ์šฉ์ด๋ผ๋ฉด, @MockBean์€ ์Šคํ”„๋ง ์ปจํ…์ŠคํŠธ์™€ ํ†ตํ•ฉ๋œ ํ…Œ์ŠคํŠธ์—์„œ ์‚ฌ์šฉ๋œ๋‹ค.

  • ๋™์ž‘ ๋ฐฉ์‹: ์Šคํ”„๋ง์˜ ApplicationContext์— ๋“ฑ๋ก๋œ ์‹ค์ œ ๋นˆ(Bean)์„ Mockito Mock ๊ฐ์ฒด๋กœ ๊ต์ฒด

  • ์ฃผ์š” ์‚ฌ์šฉ์ฒ˜

    • @WebMvcTest: ์ปจํŠธ๋กค๋Ÿฌ ํ…Œ์ŠคํŠธ ์‹œ, ํ•˜์œ„ ๊ณ„์ธต์ธ Service๋ฅผ Mock ๊ฐ์ฒด๋กœ ๋Œ€์ฒดํ•  ๋•Œ ์‚ฌ์šฉ

    • @SpringBootTest: ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ ์ค‘, ์™ธ๋ถ€ API ํ˜ธ์ถœ (ApiClient) ๋“ฑ ํŠน์ • ๋นˆ๋งŒ ๊ฐ€์งœ๋กœ ๋Œ€์ฒดํ•  ๋•Œ ์‚ฌ์šฉ

@MockBean์ด๋‚˜ @SpyBean์„ ์‚ฌ์šฉํ•˜๋ฉด, ๊ธฐ์กด๊ณผ ๋‹ค๋ฅธ ์„ค์ •์˜ ์ปจํ…์ŠคํŠธ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๊ณ  ๊ฐ„์ฃผ๋˜์–ด ์ปจํ…์ŠคํŠธ ์บ์‹œ๊ฐ€ ์žฌ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค.

2. Stubbing - ํ–‰๋™ ์ •์˜

Mock ๊ฐ์ฒด๊ฐ€ ํŠน์ • ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ์— ์–ด๋–ป๊ฒŒ ์‘๋‹ตํ• ์ง€ ๋ฏธ๋ฆฌ ์ •์˜ํ•˜๋Š” ๊ณผ์ •์ด๋‹ค.

when() ๊ณ„์—ด

๋ฐ˜ํ™˜๊ฐ’์ด ์žˆ๋Š” ๋ฉ”์„œ๋“œ์˜ ํ–‰๋™์„ ์ •์˜ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

  • thenReturn(value): ๊ณ ์ •๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜

  • thenThrow(exception): ์˜ˆ์™ธ ๋ฐœ์ƒ

  • thenAnswer(answer): ๋™์ ์ธ ๋กœ์ง์„ ํ†ตํ•ด ๊ณ„์‚ฐ๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜

do*() ๊ณ„์—ด

๋ฐ˜ํ™˜๊ฐ’์ด void์ธ ๋ฉ”์„œ๋“œ๋‚˜, ์‹ค์ œ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ์„ ํ”ผํ•˜๋ฉด์„œ Stubbing ํ•ด์•ผ ํ•˜๋Š” Spy ๊ฐ์ฒด์— ์‚ฌ์šฉ๋œ๋‹ค.

  • doNothing(): ์•„๋ฌด ๋™์ž‘๋„ ํ•˜์ง€ ์•Š์Œ

  • doThrow(exception): ์˜ˆ์™ธ ๋ฐœ์ƒ

  • doAnswer(answer): ๋™์ ์ธ ๋กœ์ง์„ ์‹คํ–‰

  • doReturn(value): when() ๋Œ€์‹  ์‚ฌ์šฉํ•˜๋Š” Stubbing(Spy ๊ฐ์ฒด์— ๊ถŒ์žฅ)

BDD ์Šคํƒ€์ผ Stubbing (given/willReturn)

BDD(ํ–‰์œ„ ์ฃผ๋„ ๊ฐœ๋ฐœ) ์Šคํƒ€์ผ์„ ์„ ํ˜ธํ•˜๋Š” ๊ฒฝ์šฐ, BDDMockito๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

  • given(mock.method()): when(mock.method()) ๋™์ผ

  • willReturn(value): thenReturn(value) ๋™์ผ

3. Verification - ํ–‰์œ„ ๊ฒ€์ฆ

ํ…Œ์ŠคํŠธ ๋Œ€์ƒ ๋กœ์ง์ด ์‹คํ–‰๋œ ํ›„, Mock ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ์˜ˆ์ƒ๋Œ€๋กœ ํ˜ธ์ถœ๋˜์—ˆ๋Š”์ง€ ๊ฒ€์ฆํ•œ๋‹ค.

  • times(n): ์ •ํ™•ํžˆ n๋ฒˆ ํ˜ธ์ถœ๋˜์—ˆ๋Š”์ง€ ๊ฒ€์ฆ

  • verify(mock): ํ•ด๋‹น ๋ฉ”์„œ๋“œ๊ฐ€ 1๋ฒˆ ํ˜ธ์ถœ๋˜์—ˆ๋Š”์ง€ ๊ฒ€์ฆ(= times(1))

  • never(): ํ•œ ๋ฒˆ๋„ ํ˜ธ์ถœ๋˜์ง€ ์•Š์•˜๋Š”์ง€ ๊ฒ€์ฆ(= times(0))

  • atLeast(n) / atMost(n): ์ตœ์†Œ n๋ฒˆ / ์ตœ๋Œ€ n๋ฒˆ ํ˜ธ์ถœ๋˜์—ˆ๋Š”์ง€ ๊ฒ€์ฆ

  • inOrder(mock...): ์—ฌ๋Ÿฌ Mock ๊ฐ์ฒด์— ๊ฑธ์ณ ํ˜ธ์ถœ ์ˆœ์„œ๊ฐ€ ์ •ํ™•ํ•œ์ง€ ๊ฒ€์ฆ

  • timeout(millis): ๋น„๋™๊ธฐ ์ฝ”๋“œ ํ…Œ์ŠคํŠธ ์‹œ, ์ง€์ •๋œ ์‹œ๊ฐ„ ๋‚ด์— ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๋Š”์ง€ ๊ฒ€์ฆ

BDD ์Šคํƒ€์ผ ๊ฒ€์ฆ (then/should)

BDDMockito๋Š” ๊ฒ€์ฆ์„ ์œ„ํ•œ then/should ๋ฌธ๋ฒ•๋„ ์ œ๊ณตํ•œ๋‹ค.

4. Argument Matchers & Captors

Argument Matchers

Stubbing์ด๋‚˜ ๊ฒ€์ฆ ์‹œ, ์ธ์ž์˜ ์‹ค์ œ ๊ฐ’ ๋Œ€์‹  ์œ ์—ฐํ•œ ์กฐ๊ฑด์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์„ ๋•Œ ํ™œ์šฉํ•œ๋‹ค.

  • any(): ๋ชจ๋“  ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ํ—ˆ์šฉ(anyString(), anyInt() ๋“ฑ ํƒ€์ž…๋ณ„ Matcher ์ œ๊ณต)

  • eq(value): ํŠน์ • ๊ฐ’๊ณผ ๋™์ผํ•ด์•ผ ํ•จ์„ ๋ช…์‹œ

  • argThat(matcher): ์ปค์Šคํ…€ Matcher๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ณต์žกํ•œ ์กฐ๊ฑด ์ง€์ • ๊ฐ€๋Šฅ

์ค‘์š”ํ•œ ์ ์€ ๋ฉ”์„œ๋“œ์˜ ์—ฌ๋Ÿฌ ์ธ์ž ์ค‘ ํ•˜๋‚˜๋ผ๋„ Argument Matcher๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค๋ฉด, ๋ชจ๋“  ์ธ์ž๋ฅผ Matcher๋กœ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค.

ArgumentCaptor(์ธ์ž ์บก์ฒ˜)

Mock ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ ์ „๋‹ฌ๋œ ์‹ค์ œ ์ธ์ž ๊ฐ’์„ ํฌ์ฐฉ(Capture)ํ•˜์—ฌ, ๋‚˜์ค‘์— ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๋Š”๋‹ค.

๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ์—ฌ๋ถ€๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, "์ •ํ™•ํžˆ ์–ด๋–ค ๊ฐ’์ด ์ „๋‹ฌ๋˜์—ˆ๋Š”์ง€" ๊ทธ ๋‚ด์šฉ์„ ๊ฒ€์ฆํ•ด์•ผ ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. (์˜ˆ: save ๋ฉ”์„œ๋“œ๋กœ ์ „๋‹ฌ๋œ ๊ฐ์ฒด์˜ ํ•„๋“œ ๊ฐ’ ๊ฒ€์ฆ)

Last updated

Was this helpful?