์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ํ•ต์‹ฌ ์›์น™์ธ '์˜์กด์„ฑ ์—ญ์ „ ์›์น™'์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ์žˆ์–ด์„œ ์˜์กด์„ฑ ์ฃผ์ž…(Dependency Injection, DI)์„ ์ค‘์‹ฌ์œผ๋กœ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถ”๊ณ , ์œ ์—ฐ์„ฑ ๋ฐ ํ™•์žฅ์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” ์Šคํ”„๋ง์—์„œ ์ฃผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์„ธ ๊ฐ€์ง€ ์˜์กด์„ฑ ์ฃผ์ž… ๋ฐฉ์‹์ธ ์ƒ์„ฑ์ž ์ฃผ์ž…(Constructor Injection), ์ˆ˜์ •์ž ์ฃผ์ž…(Setter Injection), ํ•„๋“œ ์ฃผ์ž…(Field Injection)์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด๊ณ , ๊ฐ ๋ฐฉ๋ฒ•์˜ ํŠน์ง•๊ณผ ์žฅ๋‹จ์ ์„ ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

1. ์ƒ์„ฑ์ž ์ฃผ์ž…(Constructor Injection)

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

์˜ˆ์‹œ ์ฝ”๋“œ:

public class BookService {
    private final BookRepository repository;

    public BookService(BookRepository repository) {
        this.repository = repository;
    }
}

์˜ˆ์‹œ ์ฝ”๋“œ ์„ธ๋ถ€ ๋™์ž‘ ์ˆœ์„œ:

  1. BookService ๊ฐ์ฒด ์ƒ์„ฑ ์š”์ฒญ.
  2. BookRepository ์ธ์Šคํ„ด์Šค๊ฐ€ ํ•„์š”ํ•จ์„ ์Šคํ”„๋ง์ด ์ธ์ง€.
  3. BookRepository ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ๊ธฐ์กด์— ์กด์žฌํ•˜๋Š” ๋นˆ์„ ์ฐพ์Œ.
  4. BookRepository ์ธ์Šคํ„ด์Šค๋ฅผ BookService ์ƒ์„ฑ์ž์— ์ฃผ์ž…ํ•˜๋ฉฐ ๊ฐ์ฒด ์ƒ์„ฑ.
  5. ์ „์ฒด ๋™์ž‘ ์ˆœ์„œ:
  6. ์˜์กด์„ฑ ํ™•์ธ: ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์ „์— ํ•„์š”ํ•œ ์˜์กด์„ฑ์„ ๋จผ์ € ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  7. ๋นˆ ์ƒ์„ฑ ๋ฐ ์ฃผ์ž…: ํ•„์š”ํ•œ ์˜์กด์„ฑ์„ ์ƒ์„ฑ์ž์˜ ์ธ์ž๋กœ ์ „๋‹ฌํ•˜๋ฉด์„œ ๊ฐ์ฒด(๋นˆ)๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

์žฅ์ :

  • ์•ˆ์ •์„ฑ: ์˜์กด์„ฑ์ด ๋ช…์‹œ์ ์ด๋ฏ€๋กœ ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์•ˆ์ •์ ์œผ๋กœ ๊ฐ์ฒด๋ฅผ ์ดˆ๊ธฐํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋ถˆ๋ณ€์„ฑ: ์˜์กด์„ฑ ์ฃผ์ž… ํ›„์—๋Š” ๋ณ€๊ฒฝ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜์—ฌ ๊ฐ์ฒด์˜ ์ƒํƒœ๊ฐ€ ์ผ๊ด€๋ฉ๋‹ˆ๋‹ค.
  • ์ˆœํ™˜ ์ฐธ์กฐ ์˜ค๋ฅ˜ ํ™•์ธ ๊ฐ€๋Šฅ: ์„œ๋กœ ์˜์กดํ•˜๋Š” ๊ฐ์ฒด ๊ฐ„์— ์ˆœํ™˜ ์ฐธ์กฐ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒฝ์šฐ, ์Šคํ”„๋ง์€ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์—†์–ด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.(์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ๋ชจ๋“  ์˜์กด์„ฑ์ด ์ฃผ์ž…๋˜๊ธฐ ๋•Œ๋ฌธ์—, ์ˆœํ™˜ ์ฐธ์กฐ๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ ์Šคํ”„๋ง์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ดˆ๊ธฐํ™” ๋‹จ๊ณ„์—์„œ ์ด๋ฅผ ๊ฐ์ง€ํ•˜๊ณ  ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ)

2. ์ˆ˜์ •์ž ์ฃผ์ž…(Setter Injection)

์ˆ˜์ •์ž ์ฃผ์ž…์€ ๊ฐ์ฒด ์ƒ์„ฑ ํ›„, ํ•„์š”ํ•œ ์˜์กด์„ฑ์„ setter ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ฃผ์ž…ํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๊ฐ์ฒด์˜ ์ƒ์„ฑ๊ณผ ์˜์กด์„ฑ ์ฃผ์ž…์„ ๋ถ„๋ฆฌํ•˜์—ฌ ๋” ์œ ์—ฐํ•œ ๊ตฌ์„ฑ์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ์‹œ ์ฝ”๋“œ:

public class UserService {
    private UserRepository userRepository;

    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}

์˜ˆ์‹œ ์ฝ”๋“œ ์ƒ์„ธ ๋™์ž‘ ์ˆœ์„œ:

  1. UserService ๊ฐ์ฒด ์ƒ์„ฑ.
  2. ์Šคํ”„๋ง์ด UserRepository ์˜์กด์„ฑ์„ ํ™•์ธ.
  3. UserRepository ์ธ์Šคํ„ด์Šค๋ฅผ UserService์˜ setUserRepository ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ฃผ์ž….

์ „์ฒด ๋™์ž‘ ์ˆœ์„œ:

  1. ๋นˆ ์ƒ์„ฑ: ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ๋จผ์ € ๊ฐ์ฒด(๋นˆ)๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ๋Š” ์•„์ง ์˜์กด์„ฑ์ด ์ฃผ์ž…๋˜์ง€ ์•Š์€ ์ƒํƒœ์ž…๋‹ˆ๋‹ค.
  2. ์˜์กด์„ฑ ํ™•์ธ: ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ๊ฐ์ฒด์— ํ•„์š”ํ•œ ์˜์กด์„ฑ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  3. ์˜์กด์„ฑ ์ฃผ์ž…: ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ํ•ด๋‹น ๊ฐ์ฒด์˜ ์ˆ˜์ •์ž ๋ฉ”์„œ๋“œ(setter)๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•ฉ๋‹ˆ๋‹ค.

์žฅ์ :

  • ์œ ์—ฐ์„ฑ: ์˜์กด์„ฑ์„ ๋‚˜์ค‘์— ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ์–ด ์‹คํ–‰ ์ค‘์— ๊ฐ์ฒด์˜ ์˜์กด์„ฑ์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์„ ํƒ์  ์˜์กด์„ฑ: ๋ชจ๋“  ์˜์กด์„ฑ์ด ํ•„์ˆ˜๋Š” ์•„๋‹ˆ๋ฏ€๋กœ ํ•„์š”์— ๋”ฐ๋ผ ์„ ํƒ์ ์œผ๋กœ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹จ์ :

  • ๋ถˆ์™„์ „ํ•œ ๊ฐ์ฒด ์ƒ์„ฑ ๊ฐ€๋Šฅ์„ฑ: ๋ชจ๋“  ์˜์กด์„ฑ์ด ์„ค์ •๋˜๊ธฐ ์ „์— ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•  ์œ„ํ—˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.

3. ํ•„๋“œ ์ฃผ์ž…(Field Injection)

ํ•„๋“œ ์ฃผ์ž…์€ ํด๋ž˜์Šค ๋‚ด๋ถ€์˜ ํ•„๋“œ์— ์ง์ ‘ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ์ฃผ๋กœ @Autowired ์–ด๋…ธ

ํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ„ํŽธํ•˜๊ฒŒ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ์‹œ ์ฝ”๋“œ:

public class OrderService {
    @Autowired
    private PaymentService paymentService;
}

์˜ˆ์‹œ ์ฝ”๋“œ ๋™์ž‘ ์ˆœ์„œ:

  1. OrderService ๊ฐ์ฒด ์ƒ์„ฑ.
  2. ์Šคํ”„๋ง์ด PaymentService ํ•„๋“œ์— @Autowired๋ฅผ ์ธ์‹.
  3. ํ•ด๋‹น ํ•„๋“œ์— PaymentService ์ธ์Šคํ„ด์Šค๋ฅผ ์ž๋™์œผ๋กœ ์ฃผ์ž….

์ „์ฒด ๋™์ž‘ ์ˆœ์„œ:

  1. ๋นˆ ์ƒ์„ฑ: ๊ฐ์ฒด(๋นˆ)๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.
  2. ์˜์กด์„ฑ ์ฃผ์ž…: ์ƒ์„ฑ๋œ ๊ฐ์ฒด์˜ ํ•„๋“œ์— ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ถ™์–ด ์žˆ๋Š” ๊ฒฝ์šฐ, ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ํ•ด๋‹น ํ•„๋“œ์— ์ง์ ‘ ์˜์กด์„ฑ์„ ์ฃผ์ž…

์žฅ์ :

  • ๊ฐ„๊ฒฐ์„ฑ: ์ฝ”๋“œ๊ฐ€ ๊ฐ„๋‹จํ•ด์ ธ์„œ ๊ฐœ๋ฐœ ์†๋„๊ฐ€ ํ–ฅ์ƒ๋ฉ๋‹ˆ๋‹ค.
  • ํŽธ๋ฆฌ์„ฑ: ์„ค์ •์ž ๋ฉ”์„œ๋“œ๋‚˜ ์ƒ์„ฑ์ž๋ฅผ ์ •์˜ํ•  ํ•„์š” ์—†์ด ์ž๋™์œผ๋กœ ์˜์กด์„ฑ์ด ๊ด€๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

๋‹จ์ :

  • ํ…Œ์ŠคํŠธ ์–ด๋ ค์›€: ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์‹œ ์˜์กด์„ฑ์„ ๋ช…์‹œ์ ์œผ๋กœ ์ œ๊ณตํ•˜๊ธฐ ์–ด๋ ค์›Œ์ง‘๋‹ˆ๋‹ค.

์ฆ‰ ์™ ๋งŒํ•ด์„  ์ƒ์„ฑ์ž ์ฃผ์ž…์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋ฉฐ

์ƒ์„ฑ์ž ์ฃผ์ž…์˜ ์žฅ์ ์„ ์ „์ฒด์ ์œผ๋กœ ์ž์„ธํžˆ ๋‚˜์—ดํ•ด๋ณด๊ฒ ๋‹ค

์™œ ์ƒ์„ฑ์ž ์ฃผ์ž…์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”๊ฐ€?

1. ์˜์กด์„ฑ ๋ช…ํ™•์„ฑ๊ณผ ์•ˆ์ „์„ฑ

์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์˜์กด์„ฑ์„ ์ฃผ์ž…๋ฐ›๋Š” ๋ฐฉ์‹์€ ๋ชจ๋“  ํ•„์ˆ˜ ์˜์กด์„ฑ์ด ์ƒ์„ฑ ์‹œ์ ์— ์ œ๊ณต๋˜์–ด์•ผ ํ•จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ด ์ ‘๊ทผ ๋ฐฉ์‹์€ ์˜์กด์„ฑ ๋ˆ„๋ฝ์„ ๋ฐฉ์ง€ํ•˜๊ณ , ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜์˜ ๊ฐ€๋Šฅ์„ฑ์„ ์ค„์ž…๋‹ˆ๋‹ค.

์˜ˆ์‹œ ์ฝ”๋“œ:

public class AccountService {
    private final AccountRepository accountRepository;
    private final NotificationService notificationService;

    public AccountService(AccountRepository accountRepository, NotificationService notificationService) {
        this.accountRepository = accountRepository;
        this.notificationService = notificationService;
    }
}

์œ„ ์ฝ”๋“œ์—์„œ AccountService๋Š” AccountRepository์™€ NotificationService์˜ ์˜์กด์„ฑ์„ ํ•„์š”๋กœ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋‘ ์ปดํฌ๋„ŒํŠธ๋Š” ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์ฃผ์ž…๋˜๋ฏ€๋กœ, AccountService ๊ฐ์ฒด๋Š” ํ•ญ์ƒ ์™„์ „ํ•œ ์ƒํƒœ๋กœ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

2. ๋ถˆ๋ณ€์„ฑ ๋ณด์žฅ

์ƒ์„ฑ์ž ์ฃผ์ž…์„ ํ†ตํ•œ ์˜์กด์„ฑ ๊ด€๋ฆฌ๋Š” ๊ฐ์ฒด์˜ ๋ถˆ๋ณ€์„ฑ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. ํ•œ ๋ฒˆ ์ฃผ์ž…๋œ ์˜์กด์„ฑ์€ ๊ฐ์ฒด์˜ ์ƒ๋ช…์ฃผ๊ธฐ ๋™์•ˆ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์˜ˆ์‹œ ์ฝ”๋“œ:

public class Configuration {
    private final String databaseUrl;

    public Configuration(String databaseUrl) {
        this.databaseUrl = databaseUrl;
    }

    public String getDatabaseUrl() {
        return this.databaseUrl;
    }
}

Configuration ๊ฐ์ฒด๋Š” ์ƒ์„ฑ ์‹œ databaseUrl์„ ์ฃผ์ž…๋ฐ›์œผ๋ฉฐ, ์ด ๊ฐ’์€ ๊ฐ์ฒด๊ฐ€ ์กด์žฌํ•˜๋Š” ๋™์•ˆ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๊ฐ์ฒด์˜ ์ผ๊ด€๋œ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๋Š” ๋ฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

3. ์ˆœํ™˜ ์ฐธ์กฐ ๋ฐฉ์ง€

์ƒ์„ฑ์ž ์ฃผ์ž…์€ ์ˆœํ™˜ ์ฐธ์กฐ๋ฅผ ์ปดํŒŒ์ผ ์‹œ์ ์—์„œ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ์„œ๋กœ ์˜์กดํ•˜๋Š” ๊ฐ์ฒด๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ, ์Šคํ”„๋ง์€ ์ดˆ๊ธฐํ™” ์ค‘์— ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œ์ผœ ๊ฐœ๋ฐœ์ž์—๊ฒŒ ์•Œ๋ฆฝ๋‹ˆ๋‹ค.

์ˆœํ™˜ ์ฐธ์กฐ ๋ฐœ์ƒ ์˜ˆ:

public class ClassA {
    private final ClassB classB;

    public ClassA(ClassB classB) {
        this.classB = classB;
    }
}

public class ClassB {
    private final ClassA classA;

    public ClassB(ClassA classA) {
        this.classA = classA;
    }
}

์œ„ ์ฝ”๋“œ๋Š” ClassA์™€ ClassB๊ฐ€ ์„œ๋กœ๋ฅผ ํ•„์š”๋กœ ํ•˜๋ฏ€๋กœ ์ˆœํ™˜ ์ฐธ์กฐ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์Šคํ”„๋ง์€ ์ด๋ฅผ ๊ฐ์ง€ํ•˜๊ณ  ๊ฐ์ฒด ์ƒ์„ฑ์„ ์ค‘๋‹จํ•ฉ๋‹ˆ๋‹ค.

4. ํ…Œ์ŠคํŠธ ์šฉ์ด์„ฑ

์ƒ์„ฑ์ž ์ฃผ์ž…์€ ํ…Œ์ŠคํŠธ ์ค‘์— ์˜์กด์„ฑ์„ ์‰ฝ๊ฒŒ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ์‹œ์— ํ•„์š”ํ•œ ์˜์กด์„ฑ์„ ๋ชฉ ๊ฐ์ฒด๋กœ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ์‹œ ์ฝ”๋“œ:

public class UserServiceTest {
    @Test
    public void testUserService() {
        UserRepository mockRepository = mock(UserRepository.class);
        NotificationService mockService = mock(NotificationService.class);
        UserService userService = new UserService(mockRepository, mockService);

        // ํ…Œ์ŠคํŠธ ์‹คํ–‰
        userService.performUpdate();

        // ์ƒํƒœ ๊ฒ€์ฆ
        verify(mockRepository).update(any(User.class));
        verify(mockService).sendNotification(any(String.class));
    }
}

์œ„ ์ฝ”๋“œ์—์„œ UserService์˜ ํ…Œ์ŠคํŠธ๋Š” ๋ชฉ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์ฃผ์ž…ํ•˜์—ฌ, ์‹ค์ œ ์˜์กด์„ฑ์„ ๋ชจ๋ฐฉํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฐฉ์‹์€ ํ…Œ์ŠคํŠธ๊ฐ€ ์˜์กด์„ฑ์˜ ๊ตฌ์ฒด์ ์ธ ๊ตฌํ˜„์— ๋ฌถ์ด์ง€ ์•Š๋„๋ก ํ•ด์ค๋‹ˆ๋‹ค.