Mockito🍸

LzhtkΒ·2025λ…„ 6μ›” 22일

μ˜€λŠ˜μ€ ν…ŒμŠ€νŠΈμ—μ„œ μ‚¬μš©ν•˜λŠ” λŒ€ν‘œμ μΈ κΈ°λŠ₯인 Mockito의 Mock, Stub, Spy에 λŒ€ν•΄ μ•Œμ•„λ³΄κ³ , μ–Έμ œ μ–΄λ–€ κ±Έ μ¨μ•Όν•˜λŠ”μ§€ μ‹€μ œ μ˜ˆμ œμ™€ ν•¨κ»˜ μ•Œμ•„λ³΄μžβ—β•


1. Mock

πŸ“Œ κ°œλ…

  • Mock은 μ‹€μ œ κ΅¬ν˜„μ„ μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” κ°€μ§œ 개체둜, μ •μ˜ν•œ λ™μž‘κ³Ό μƒν˜Έμž‘μš©λ§Œ κ²€μ¦ν•œλ‹€.

  • μ •μ˜ν•˜μ§€ μ•Šμ€ λ©”μ„œλ“œλŠ” 기본적으둜 null, 0 , falseλ₯Ό λ°˜ν™˜

  • μ½”λ“œμ˜ˆμ‹œ

@Mock
private UserRepository userRepository;

when(userRepository.findById(1L))
    .thenReturn(Optional.of(new User()));

πŸ“Œ μ–Έμ œ μ‚¬μš©ν• κΉŒ?

  • μ΄λŸ¬ν•œ Mock κ°œμ²΄λŠ” μ™ΈλΆ€ μ‹œμŠ€ν…œμ— μ˜μ‘΄ν•˜λŠ” 객체의 호좜만 κ²€μ¦ν•˜κ³  싢을 λ•Œ ν–‰μœ„ 쀑심 ν…ŒμŠ€νŠΈκ°€ ν•„μš”ν•œ 경우 μ‚¬μš©ν•œλ‹€.
  • μ‹€μ œ 예제
    • Repository λ©”μ„œλ“œκ°€ ν˜ΈμΆœλ˜μ—ˆλŠ”μ§€λ§Œ 확인
    • 결제 μ„œλ²„λ₯Ό ν…ŒμŠ€νŠΈν•  λ•Œ μ‹€μ œ 결제 APIλ₯Ό ν˜ΈμΆœν•˜μ§€ μ•Šκ³  Mock을 톡해 ν•΄λ‹Ή APIκ°€ μ˜¬λ°”λ₯Έ νŒŒλΌλ―Έν„°λ‘œ ν˜ΈμΆœλ˜μ—ˆλŠ”μ§€ 검증

2. Stub

πŸ“Œ κ°œλ…

  • νŠΉμ • ν˜ΈμΆœμ— λŒ€ν•΄ κ³ μ •λœ κ°’λ§Œ λ°˜ν™˜ν•˜λŠ” 객체이닀.
  • λ™μž‘ μžμ²΄λŠ” μ€‘μš”ν•˜μ§€ μ•Šκ³ , 예츑 κ°€λŠ₯ν•œ μ‘λ‹΅λ§Œ ν•„μš”ν•  λ•Œ μ‚¬μš©ν•œλ‹€.

πŸ’‘ Mockitoμ—μ„œ Stub은 λ³„λ„μ˜ 객체 νƒ€μž…μ΄ μ•„λ‹ˆλΌ, Mock 객체에 νŠΉμ • λ°˜ν™˜κ°’μ„ μ„€μ •ν•œ μ‚¬μš© 방식( μ—­ν•  )을 μ˜λ―Έν•œλ‹€.

  • μ½”λ“œ μ˜ˆμ‹œ
when(calculator.add(2, 3)).thenReturn(5);

πŸ“Œ μ–Έμ œ μ‚¬μš©ν• κΉŒ?

  • λ‹¨μˆœν•œ μ‹œλ‚˜λ¦¬μ˜€λ‘œ "A값이 λ“€μ–΄μ˜€λ©΄ B값을 쀘!"같은 상황이 μ£Όμ–΄μ‘Œμ„ λ•Œ ❕

  • μ™ΈλΆ€ APIλ‚˜ μ‹œμŠ€ν…œμ„ λŒ€μ²΄ν•΄ μ •ν•΄μ§„ μ‘λ‹΅λ§Œ μ£Όκ³  싢은 경우 ❗

  • μ‹€μ œ 예제

    • μ™ΈλΆ€ APIλ‘œλΆ€ν„° κ³ μ • ν™˜μœ¨ 값을 λ°›μ•„μ˜€λŠ” Test
    • μ‚¬μš©μž μ„œλΉ„μŠ€κ°€ λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œ νŠΉμ • μ‚¬μš©μžλ₯Ό μ°Ύμ•„μ•Ό ν•  λ•Œ, λ ˆν¬μ§€ν† λ¦¬ 계측을 Stub으둜 λŒ€μ²΄ν•˜μ—¬ 항상 νŠΉμ • μ‚¬μš©μž 객체λ₯Ό λ°˜ν™˜ν•˜λ„λ‘ ν•  λ•Œ

3. Spy

πŸ“Œ κ°œλ…

  • μ‹€μ œ 객체λ₯Ό 감싸고 μΌλΆ€λ§Œ Stubbing κ°€λŠ₯ν•˜λ‹€
  • λ‚˜λ¨Έμ§€λŠ” μ‹€μ œ 객체처럼 κ·ΈλŒ€λ‘œ λ™μž‘

⚠️ SpyλŠ” μ‹€μ œ λ‘œμ§μ„ μ‹€ν–‰ν•˜λ―€λ‘œ, μ™ΈλΆ€ μ˜μ‘΄μ„±μ΄λ‚˜ μƒνƒœ 변경이 μžˆλŠ” κ°μ²΄μ—λŠ” μ£Όμ˜ν•΄μ„œ μ‚¬μš©ν•΄μ•Ό ν•œλ‹€.

  • μ½”λ“œ μ˜ˆμ‹œ
@Spy
private List<String> list = new ArrayList<>();

@Test
void testSpy() {
    list.add("one");              // μ‹€μ œ λ™μž‘
    when(list.size()).thenReturn(100); // μΌλΆ€λ§Œ μŠ€ν…
}

πŸ“Œ μ–Έμ œ μ‚¬μš©ν• κΉŒ?

  • λŒ€λΆ€λΆ„μ˜ λ™μž‘μ€ μ‹€μ œ 객체둜 μ‚¬μš©ν•˜λ˜, 일뢀 λ™μž‘λ§Œ ν†΅μ œν•˜κ³  싢을 λ•Œ ❗

  • λ©”μ„œλ“œ 호좜 μ—¬λΆ€λ₯Ό κ°μ‹œν•˜λ©΄μ„œ μ‹€μ œ λ‘œμ§λ„ μ‹€ν–‰ν•˜κ³  싢은 경우 ❕

  • μ‹€μ œ 예제

    • μ‹€μ œ μ„œλΉ„μŠ€ 객체λ₯Ό μ‚¬μš©ν•˜λ©° μΊμ‹œ λ©”μ„œλ“œλ§Œ ν†΅μ œ
    • 둜그 μ„œλΉ„μŠ€μ—μ„œ λŒ€λΆ€λΆ„μ˜ μ‹€μ œ λ©”μ†Œλ“œλŠ” μ‹€μ œλ‘œ μ‹€ν–‰ν•˜λ˜, νŠΉμ • λ‘œκΉ… λ©”μ†Œλ“œλ§Œ κ²€μ¦ν•˜κ³  싢을 λ•Œ

마무리 πŸ”š

λ‹¨μœ„ ν…ŒμŠ€νŠΈμ—μ„œ μ€‘μš”ν•œ 건 독립성과 ν†΅μ œλ ₯이닀.
Mockito의 Mock, Stub, Spyλ₯Ό 적절히 μ‚¬μš©ν•˜μ—¬ μ™ΈλΆ€ μ˜μ‘΄μ„±μ„ κ²©λ¦¬ν•˜κ³ , μ›ν•˜λŠ” λ°©μ‹μœΌλ‘œ λ™μž‘μ„ μ œμ–΄ν•˜λ©° ν…ŒμŠ€νŠΈ ν’ˆμ§ˆμ„ 크게 ν–₯μƒμ‹œν‚¬ 수 μžˆλ„λ‘ ν•˜μžπŸ’―

0개의 λŒ“κΈ€