Search
moon
sun

@Mock, @MockBean, @Spy @SpyBean @InjectMocks

ํƒœ๊ทธ
Spring
Java
Test
๋‹ด๋‹น์ž
์ƒ์„ฑ์ผ
2024/10/25
์ˆœ์„œ
9

@Mock

์ •์˜
โ€ข
๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ๊ฐ€์งœ(Mock) ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ
โ€ข
์‹ค์ œ ๊ฐ์ฒด ์—†์ด๋„ ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅ
ํŠน์ง•
โ€ข
๋ชจ๋“  ๋ฉ”์†Œ๋“œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์•„๋ฌด ๋™์ž‘๋„ ํ•˜์ง€ ์•Š์Œ
โ€ข
when().thenReturn() ๋“ฑ์œผ๋กœ ์›ํ•˜๋Š” ๋™์ž‘ ์ •์˜ ํ•„์š”
โ€ข
๋‹จ์œ„ ํ…Œ์ŠคํŠธ์—์„œ ์ฃผ๋กœ ์‚ฌ์šฉ
@ExtendWith(MockitoExtension.class) class MailServiceTest { @Mock private MailSendClient mailSendClient; @Mock private MailSendHistoryRepository mailSendHistoryRepository; @InjectMocks private MailService mailService; @DisplayName("๋ฉ”์ผ ์ „์†ก ํ…Œ์ŠคํŠธ - Mock ์‚ฌ์šฉ") @Test void sendMailTest() { // given String to = "test@test.com"; String subject = "ํ…Œ์ŠคํŠธ"; String content = "ํ…Œ์ŠคํŠธ ๋‚ด์šฉ"; String fromEmail = "from@test.com"; //๋™์ž‘ ์ •์˜ when(mailSendClient.sendEmail(anyString(), anyString(), anyString(), anyString())) .thenReturn(true); // when boolean result = mailService.sendEmail(to, subject, content, fromEmail); // then assertThat(result).isTrue(); verify(mailSendClient, times(1)) .sendEmail(to, subject, content, fromEmail); } }
Java
๋ณต์‚ฌ

@MockBean

์ •์˜
โ€ข
์Šคํ”„๋ง ์ปจํ…์ŠคํŠธ์—์„œ ํŠน์ • ๋นˆ์„ ๊ฐ€์งœ ๊ฐ์ฒด๋กœ ๋Œ€์ฒด
โ€ข
ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ์—์„œ ์‚ฌ์šฉ
ํŠน์ง•
โ€ข
์Šคํ”„๋ง ๋ถ€ํŠธ ํ…Œ์ŠคํŠธ์—์„œ ์‚ฌ์šฉ
โ€ข
ApplicationContext์— Mock ๊ฐ์ฒด๋ฅผ ๋“ฑ๋ก
โ€ข
๊ธฐ์กด์— ๋“ฑ๋ก๋œ ๋นˆ์„ Mock์œผ๋กœ ๊ต์ฒด
@SpringBootTest class MailServiceIntegrationTest { @MockBean private MailSendClient mailSendClient; @Autowired private MailService mailService; @DisplayName("๋ฉ”์ผ ์ „์†ก ํ…Œ์ŠคํŠธ - MockBean ์‚ฌ์šฉ") @Test void sendMailTest() { // given String to = "test@test.com"; String subject = "ํ…Œ์ŠคํŠธ"; String content = "ํ…Œ์ŠคํŠธ ๋‚ด์šฉ"; String fromEmail = "from@test.com"; //๋™์ž‘ ์ •์˜ when(mailSendClient.sendEmail(anyString(), anyString(), anyString(), anyString())) .thenReturn(true); // when boolean result = mailService.sendEmail(to, subject, content, fromEmail); // then assertThat(result).isTrue(); } }
Java
๋ณต์‚ฌ

@InjectMocks

์ •์˜
โ€ข
@Mock์œผ๋กœ ์ƒ์„ฑ๋œ ๊ฐ์ฒด๋“ค์„ ์ž๋™์œผ๋กœ ์ฃผ์ž…
โ€ข
์˜์กด์„ฑ ์ฃผ์ž…(DI)์„ ํ…Œ์ŠคํŠธ์—์„œ ๊ตฌํ˜„
ํŠน์ง•
โ€ข
@Mock ๊ฐ์ฒด๋“ค์„ ์ž๋™์œผ๋กœ ์ฃผ์ž…๋ฐ›์Œ
โ€ข
์ƒ์„ฑ์ž, ์„ธํ„ฐ, ํ•„๋“œ ์ฃผ์ž… ์ง€์›
โ€ข
์—ฌ๋Ÿฌ Mock ๊ฐ์ฒด๋“ค์˜ ์˜์กด ๊ด€๊ณ„ ์„ค์ • ์‹œ ์œ ์šฉ

@Spy

์ •์˜
โ€ข
์‹ค์ œ ๊ฐ์ฒด์˜ ์ผ๋ถ€ ๋ฉ”์†Œ๋“œ๋งŒ Mock์œผ๋กœ ์ง€์ •
โ€ข
๋‚˜๋จธ์ง€๋Š” ์‹ค์ œ ๊ฐ์ฒด์˜ ๋ฉ”์†Œ๋“œ ์‚ฌ์šฉ
ํŠน์ง•
โ€ข
์‹ค์ œ ๊ฐ์ฒด์˜ ๋ฉ”์†Œ๋“œ๋ฅผ ์„ ํƒ์ ์œผ๋กœ ์˜ค๋ฒ„๋ผ์ด๋“œ
โ€ข
ํŠน์ • ๋ฉ”์†Œ๋“œ๋งŒ ์Šคํ„ฐ๋น™ํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์œ ์šฉ
โ€ข
๋ถ€๋ถ„์ ์ธ Mock์ด ํ•„์š”ํ•  ๋•Œ ์‚ฌ์šฉ
@ExtendWith(MockitoExtension.class) class MailServiceTest { @Spy private MailSendClient mailSendClient; @Mock private MailSendHistoryRepository mailSendHistoryRepository; @InjectMocks private MailService mailService; @DisplayName("๋ฉ”์ผ ์ „์†ก ํ…Œ์ŠคํŠธ - Spy ์‚ฌ์šฉ") @Test void sendMailTest() { // given String to = "test@test.com"; String subject = "ํ…Œ์ŠคํŠธ"; String content = "ํ…Œ์ŠคํŠธ ๋‚ด์šฉ"; String fromEmail = "from@test.com"; // ํŠน์ • ๋ฉ”์†Œ๋“œ๋งŒ ์Šคํ„ฐ๋น™ doReturn(true) .when(mailSendClient) .sendEmail(anyString(), anyString(), anyString(), anyString()); // when boolean result = mailService.sendEmail(to, subject, content, fromEmail); // then assertThat(result).isTrue(); // ์‹ค์ œ ํ˜ธ์ถœ ์—ฌ๋ถ€ ํ™•์ธ verify(mailSendClient, times(1)) .sendEmail(to, subject, content, fromEmail); } }
Java
๋ณต์‚ฌ

@SpyBean

์ •์˜
โ€ข
์Šคํ”„๋ง ๋นˆ์˜ ์ผ๋ถ€ ๋ฉ”์†Œ๋“œ๋งŒ Mock์œผ๋กœ ๊ต์ฒด
โ€ข
๋‚˜๋จธ์ง€๋Š” ์‹ค์ œ ๋นˆ์˜ ๋™์ž‘ ์œ ์ง€
ํŠน์ง•
โ€ข
์Šคํ”„๋ง ์ปจํ…์ŠคํŠธ์—์„œ ๋™์ž‘
โ€ข
์‹ค์ œ ๋นˆ์˜ ์ผ๋ถ€ ๋™์ž‘๋งŒ ์ˆ˜์ • ๊ฐ€๋Šฅ
โ€ข
ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ์—์„œ ๋ถ€๋ถ„์ ์ธ Mock์ด ํ•„์š”ํ•  ๋•Œ ์‚ฌ์šฉ
@SpringBootTest class MailServiceIntegrationTest { @SpyBean private MailSendClient mailSendClient; @Autowired private MailService mailService; @DisplayName("๋ฉ”์ผ ์ „์†ก ํ…Œ์ŠคํŠธ - SpyBean ์‚ฌ์šฉ") @Test void sendMailTest() { // given String to = "test@test.com"; String subject = "ํ…Œ์ŠคํŠธ"; String content = "ํ…Œ์ŠคํŠธ ๋‚ด์šฉ"; String fromEmail = "from@test.com"; // ํŠน์ • ๋ฉ”์†Œ๋“œ๋งŒ ์Šคํ„ฐ๋น™ํ•˜๊ณ  ๋‚˜๋จธ์ง€๋Š” ์‹ค์ œ ๋™์ž‘ ์ˆ˜ํ–‰ doReturn(true) .when(mailSendClient) .sendEmail(anyString(), anyString(), anyString(), anyString()); // when boolean result = mailService.sendEmail(to, subject, content, fromEmail); // then assertThat(result).isTrue(); } }
Java
๋ณต์‚ฌ

๋ฌธ์ œ

์•„๋ž˜ 3๊ฐœ์˜ ํ…Œ์ŠคํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด์šฉ์„ ์‚ดํŽด๋ณด๊ณ , ๊ฐ ํ•ญ๋ชฉ์„ @BeforeEach, given์ ˆ, when์ ˆ์— ๋ฐฐ์น˜ํ•œ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ฐฐ์น˜ํ•˜๊ณ  ์‹ถ์œผ์‹ ๊ฐ€์š”? (@BeforeEach์— ์˜ฌ๋ผ๊ฐ„ ๋‚ด์šฉ์€ ๊ณตํ†ต ํ•ญ๋ชฉ์œผ๋กœ ํ•ฉ์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ex. 1-1๊ณผ 2-1์„ ํ•˜๋‚˜๋กœ ํ•ฉ์ณ์„œ @BeforeEach์— ๋ฐฐ์น˜)
@BeforeEach void setUp() { โ“ } @DisplayName("์‚ฌ์šฉ์ž๊ฐ€ ๋Œ“๊ธ€์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.") @Test void writeComment() { 1-1. ์‚ฌ์šฉ์ž ์ƒ์„ฑ์— ํ•„์š”ํ•œ ๋‚ด์šฉ ์ค€๋น„ 1-2. ์‚ฌ์šฉ์ž ์ƒ์„ฑ 1-3. ๊ฒŒ์‹œ๋ฌผ ์ƒ์„ฑ์— ํ•„์š”ํ•œ ๋‚ด์šฉ ์ค€๋น„ 1-4. ๊ฒŒ์‹œ๋ฌผ ์ƒ์„ฑ 1-5. ๋Œ“๊ธ€ ์ƒ์„ฑ์— ํ•„์š”ํ•œ ๋‚ด์šฉ ์ค€๋น„ 1-6. ๋Œ“๊ธ€ ์ƒ์„ฑ // given โ“ // when โ“ // then ๊ฒ€์ฆ } @DisplayName("์‚ฌ์šฉ์ž๊ฐ€ ๋Œ“๊ธ€์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.") @Test void updateComment() { 2-1. ์‚ฌ์šฉ์ž ์ƒ์„ฑ์— ํ•„์š”ํ•œ ๋‚ด์šฉ ์ค€๋น„ 2-2. ์‚ฌ์šฉ์ž ์ƒ์„ฑ 2-3. ๊ฒŒ์‹œ๋ฌผ ์ƒ์„ฑ์— ํ•„์š”ํ•œ ๋‚ด์šฉ ์ค€๋น„ 2-4. ๊ฒŒ์‹œ๋ฌผ ์ƒ์„ฑ 2-5. ๋Œ“๊ธ€ ์ƒ์„ฑ์— ํ•„์š”ํ•œ ๋‚ด์šฉ ์ค€๋น„ 2-6. ๋Œ“๊ธ€ ์ƒ์„ฑ 2-7. ๋Œ“๊ธ€ ์ˆ˜์ • // given โ“ // when โ“ // then ๊ฒ€์ฆ } @DisplayName("์ž์‹ ์ด ์ž‘์„ฑํ•œ ๋Œ“๊ธ€์ด ์•„๋‹ˆ๋ฉด ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๋‹ค.") @Test void cannotUpdateCommentWhenUserIsNotWriter() { 3-1. ์‚ฌ์šฉ์ž1 ์ƒ์„ฑ์— ํ•„์š”ํ•œ ๋‚ด์šฉ ์ค€๋น„ 3-2. ์‚ฌ์šฉ์ž1 ์ƒ์„ฑ 3-3. ์‚ฌ์šฉ์ž2 ์ƒ์„ฑ์— ํ•„์š”ํ•œ ๋‚ด์šฉ ์ค€๋น„ 3-4. ์‚ฌ์šฉ์ž2 ์ƒ์„ฑ 3-5. ์‚ฌ์šฉ์ž1์˜ ๊ฒŒ์‹œ๋ฌผ ์ƒ์„ฑ์— ํ•„์š”ํ•œ ๋‚ด์šฉ ์ค€๋น„ 3-6. ์‚ฌ์šฉ์ž1์˜ ๊ฒŒ์‹œ๋ฌผ ์ƒ์„ฑ 3-7. ์‚ฌ์šฉ์ž1์˜ ๋Œ“๊ธ€ ์ƒ์„ฑ์— ํ•„์š”ํ•œ ๋‚ด์šฉ ์ค€๋น„ 3-8. ์‚ฌ์šฉ์ž1์˜ ๋Œ“๊ธ€ ์ƒ์„ฑ 3-9. ์‚ฌ์šฉ์ž2๊ฐ€ ์‚ฌ์šฉ์ž1์˜ ๋Œ“๊ธ€ ์ˆ˜์ • ์‹œ๋„ // given โ“ // when โ“ // then ๊ฒ€์ฆ }
Java
๋ณต์‚ฌ
@BeforeEach void setUp() { (1-1. ์‚ฌ์šฉ์ž ์ƒ์„ฑ์— ํ•„์š”ํ•œ ๋‚ด์šฉ ์ค€๋น„ ,3-1. ์‚ฌ์šฉ์ž1 ์ƒ์„ฑ์— ํ•„์š”ํ•œ ๋‚ด์šฉ ์ค€๋น„, 3-3. ์‚ฌ์šฉ์ž2 ์ƒ์„ฑ์— ํ•„์š”ํ•œ ๋‚ด์šฉ ์ค€๋น„) (1-3. ๊ฒŒ์‹œ๋ฌผ ์ƒ์„ฑ์— ํ•„์š”ํ•œ ๋‚ด์šฉ ์ค€๋น„ , 3-5. ์‚ฌ์šฉ์ž1์˜ ๊ฒŒ์‹œ๋ฌผ ์ƒ์„ฑ์— ํ•„์š”ํ•œ ๋‚ด์šฉ ์ค€๋น„) (1-5. ๋Œ“๊ธ€ ์ƒ์„ฑ์— ํ•„์š”ํ•œ ๋‚ด์šฉ ์ค€๋น„, 3-7. ์‚ฌ์šฉ์ž1์˜ ๋Œ“๊ธ€ ์ƒ์„ฑ์— ํ•„์š”ํ•œ ๋‚ด์šฉ ์ค€๋น„) } @DisplayName(""์‚ฌ์šฉ์ž๊ฐ€ ๋Œ“๊ธ€์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค."") @Test void writeComment() { // given 1-2. ์‚ฌ์šฉ์ž ์ƒ์„ฑ 1-4. ๊ฒŒ์‹œ๋ฌผ ์ƒ์„ฑ // when 1-6. ๋Œ“๊ธ€ ์ƒ์„ฑ // then ๊ฒ€์ฆ } @DisplayName(""์‚ฌ์šฉ์ž๊ฐ€ ๋Œ“๊ธ€์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค."") @Test void updateComment() { // given 2-2. ์‚ฌ์šฉ์ž ์ƒ์„ฑ 2-4. ๊ฒŒ์‹œ๋ฌผ ์ƒ์„ฑ 2-6. ๋Œ“๊ธ€ ์ƒ์„ฑ // when 2-7. ๋Œ“๊ธ€ ์ˆ˜์ • // then ๊ฒ€์ฆ } @DisplayName(""์ž์‹ ์ด ์ž‘์„ฑํ•œ ๋Œ“๊ธ€์ด ์•„๋‹ˆ๋ฉด ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๋‹ค."") @Test void cannotUpdateCommentWhenUserIsNotWriter() { // given 3-2. ์‚ฌ์šฉ์ž1 ์ƒ์„ฑ 3-4. ์‚ฌ์šฉ์ž2 ์ƒ์„ฑ 3-6. ์‚ฌ์šฉ์ž1์˜ ๊ฒŒ์‹œ๋ฌผ ์ƒ์„ฑ 3-8. ์‚ฌ์šฉ์ž1์˜ ๋Œ“๊ธ€ ์ƒ์„ฑ // when 3-9. ์‚ฌ์šฉ์ž2๊ฐ€ ์‚ฌ์šฉ์ž1์˜ ๋Œ“๊ธ€ ์ˆ˜์ • ์‹œ๋„ // then ๊ฒ€์ฆ }
Java
๋ณต์‚ฌ