1+ package org .ject .support .external .email .service ;
2+
3+ import org .ject .support .base .UnitTestSupport ;
4+ import org .ject .support .common .util .Map2JsonSerializer ;
5+ import org .ject .support .external .email .domain .EmailTemplate ;
6+ import org .ject .support .external .email .exception .EmailErrorCode ;
7+ import org .ject .support .external .email .exception .EmailException ;
8+ import org .ject .support .external .infrastructure .SesRateLimiter ;
9+ import org .junit .jupiter .api .BeforeEach ;
10+ import org .junit .jupiter .api .Test ;
11+ import org .mockito .InjectMocks ;
12+ import org .mockito .Mock ;
13+ import org .springframework .test .util .ReflectionTestUtils ;
14+ import software .amazon .awssdk .services .sesv2 .SesV2Client ;
15+ import software .amazon .awssdk .services .sesv2 .model .SendEmailRequest ;
16+ import software .amazon .awssdk .services .sesv2 .model .SendEmailResponse ;
17+
18+ import java .util .Map ;
19+
20+ import static org .assertj .core .api .Assertions .assertThatThrownBy ;
21+ import static org .mockito .ArgumentMatchers .any ;
22+ import static org .mockito .ArgumentMatchers .anyMap ;
23+ import static org .mockito .BDDMockito .given ;
24+ import static org .mockito .Mockito .verify ;
25+
26+ class SesEmailSendServiceTest extends UnitTestSupport {
27+
28+ @ InjectMocks
29+ private SesEmailSendService sesEmailSendService ;
30+
31+ @ Mock
32+ private Map2JsonSerializer map2JsonSerializer ;
33+
34+ @ Mock
35+ private SesV2Client sesV2Client ;
36+
37+ @ Mock
38+ private SesRateLimiter rateLimiter ;
39+
40+ private static final String MOCK_FROM_EMAIL = "test@example.com" ;
41+
42+ @ BeforeEach
43+ void setUp () {
44+ ReflectionTestUtils .setField (sesEmailSendService , "from" , MOCK_FROM_EMAIL );
45+ }
46+
47+ @ Test
48+ void 이메일_전송에_실패할_경우_EMAIL_SEND_FAILURE_예외_발생 () {
49+ // given
50+ String to = "user@recipient.com" ;
51+ String subject = "Test Subject" ;
52+ String htmlBody = "<h1>Test Body</h1>" ;
53+
54+ SendEmailResponse mockResponse = SendEmailResponse .builder ()
55+ .messageId ("mock-message-id-123" )
56+ .build ();
57+ given (map2JsonSerializer .serializeAsString (anyMap ())).willReturn ("{\" key\" :\" value\" }" );
58+ given (sesV2Client .sendEmail (any (SendEmailRequest .class )))
59+ .willThrow (new RuntimeException ("Simulated SES send failure" ));
60+
61+ // when, then
62+ assertThatThrownBy (() -> sesEmailSendService .sendTemplatedEmail ( EmailTemplate .AUTH_CODE ,
63+ to ,
64+ Map .of ("subject" , subject , "htmlBody" , htmlBody )
65+ ))
66+ .isInstanceOf (EmailException .class )
67+ .extracting (e -> ((EmailException ) e ).getErrorCode ())
68+ .isEqualTo (EmailErrorCode .EMAIL_SEND_FAILURE );
69+ }
70+
71+ @ Test
72+ void 이메일_전송_성공_시_SES_Client_호출_검증 () {
73+ // given
74+ String to = "user@recipient.com" ;
75+ String subject = "Test Subject" ;
76+ String htmlBody = "<h1>Test Body</h1>" ;
77+
78+ SendEmailResponse mockResponse = SendEmailResponse .builder ()
79+ .messageId ("mock-message-id-123" )
80+ .build ();
81+ given (map2JsonSerializer .serializeAsString (anyMap ())).willReturn ("{\" key\" :\" value\" }" );
82+ given (sesV2Client .sendEmail (any (SendEmailRequest .class ))).willReturn (mockResponse );
83+
84+ // when
85+ sesEmailSendService .sendTemplatedEmail (
86+ EmailTemplate .AUTH_CODE ,
87+ to ,
88+ Map .of ("subject" , subject , "htmlBody" , htmlBody )
89+ );
90+
91+ // then
92+ verify (map2JsonSerializer ).serializeAsString (anyMap ());
93+ verify (sesV2Client ).sendEmail (any (SendEmailRequest .class ));
94+ }
95+ }
0 commit comments