1212import static org .mockito .Mockito .when ;
1313
1414import io .f1 .backend .global .exception .CustomException ;
15- import java . util . concurrent . TimeUnit ;
15+
1616import org .aspectj .lang .ProceedingJoinPoint ;
1717import org .aspectj .lang .reflect .MethodSignature ;
1818import org .junit .jupiter .api .BeforeEach ;
3030import org .redisson .api .RLock ;
3131import org .redisson .api .RedissonClient ;
3232
33+ import java .util .concurrent .TimeUnit ;
34+
3335@ TestMethodOrder (MethodOrderer .OrderAnnotation .class )
3436@ ExtendWith (MockitoExtension .class )
3537class DistributedLockAspectTests {
3638
37- @ InjectMocks
38- DistributedLockAspect distributedLockAspect ;
39+ @ InjectMocks DistributedLockAspect distributedLockAspect ;
3940
40- @ Mock
41- RedissonClient redissonClient ;
41+ @ Mock RedissonClient redissonClient ;
4242
43- @ Mock
44- RLock rLock ;
43+ @ Mock RLock rLock ;
4544
46- @ Mock
47- ProceedingJoinPoint joinPoint ;
45+ @ Mock ProceedingJoinPoint joinPoint ;
4846
49- @ Mock
50- MethodSignature methodSignature ;
47+ @ Mock MethodSignature methodSignature ;
5148
52- @ Mock
53- DistributedLock distributedLockAnnotation ;
49+ @ Mock DistributedLock distributedLockAnnotation ;
5450
5551 private final String TEST_PREFIX = "room" ;
5652 private final String TEST_KEY = "#roomId" ;
@@ -69,8 +65,8 @@ void setUp() {
6965 when (distributedLockAnnotation .timeUnit ()).thenReturn (TimeUnit .SECONDS );
7066
7167 when (joinPoint .getSignature ()).thenReturn (methodSignature );
72- when (methodSignature .getParameterNames ()).thenReturn (new String []{"roomId" });
73- when (joinPoint .getArgs ()).thenReturn (new Object []{TEST_ROOM_ID });
68+ when (methodSignature .getParameterNames ()).thenReturn (new String [] {"roomId" });
69+ when (joinPoint .getArgs ()).thenReturn (new Object [] {TEST_ROOM_ID });
7470 }
7571
7672 @ Order (1 )
@@ -84,23 +80,26 @@ void testLock_Success() throws Throwable {
8480 when (rLock .isHeldByCurrentThread ()).thenReturn (true );
8581 when (joinPoint .proceed ()).thenReturn (EXPECTED_RETURN_VALUE );
8682
87- try (MockedStatic <CustomSpringELParser > mockedParser = Mockito .mockStatic (CustomSpringELParser .class )) {
88- mockedParser .when (() -> CustomSpringELParser .getDynamicValue (
89- any (String [].class ), any (Object [].class ), anyString ()
90- )).thenReturn (TEST_ROOM_ID );
83+ try (MockedStatic <CustomSpringELParser > mockedParser =
84+ Mockito .mockStatic (CustomSpringELParser .class )) {
85+ mockedParser
86+ .when (
87+ () ->
88+ CustomSpringELParser .getDynamicValue (
89+ any (String [].class ), any (Object [].class ), anyString ()))
90+ .thenReturn (TEST_ROOM_ID );
9191
9292 // When
9393 Object result = distributedLockAspect .lock (joinPoint , distributedLockAnnotation );
9494
9595 // Then
9696 assertAll (
97- () -> assertEquals (EXPECTED_RETURN_VALUE , result ),
98- () -> verify (redissonClient , times (1 )).getLock (EXPECTED_LOCK_KEY ),
99- () -> verify (rLock , times (1 )).tryLock (WAIT_TIME , LEASE_TIME , TimeUnit .SECONDS ),
100- () -> verify (joinPoint , times (1 )).proceed (),
101- () -> verify (rLock , times (1 )).isHeldByCurrentThread (),
102- () -> verify (rLock , times (1 )).unlock ()
103- );
97+ () -> assertEquals (EXPECTED_RETURN_VALUE , result ),
98+ () -> verify (redissonClient , times (1 )).getLock (EXPECTED_LOCK_KEY ),
99+ () -> verify (rLock , times (1 )).tryLock (WAIT_TIME , LEASE_TIME , TimeUnit .SECONDS ),
100+ () -> verify (joinPoint , times (1 )).proceed (),
101+ () -> verify (rLock , times (1 )).isHeldByCurrentThread (),
102+ () -> verify (rLock , times (1 )).unlock ());
104103 }
105104 }
106105
@@ -114,23 +113,28 @@ void testLock_FailToAcquireLock() throws Throwable {
114113 // 무조건 false 반환 하도록 강제
115114 when (rLock .tryLock (WAIT_TIME , LEASE_TIME , TimeUnit .SECONDS )).thenReturn (false );
116115
117- try (MockedStatic <CustomSpringELParser > mockedParser = Mockito .mockStatic (CustomSpringELParser .class )) {
118- mockedParser .when (() -> CustomSpringELParser .getDynamicValue (
119- any (String [].class ), any (Object [].class ), anyString ()
120- )).thenReturn (TEST_ROOM_ID );
116+ try (MockedStatic <CustomSpringELParser > mockedParser =
117+ Mockito .mockStatic (CustomSpringELParser .class )) {
118+ mockedParser
119+ .when (
120+ () ->
121+ CustomSpringELParser .getDynamicValue (
122+ any (String [].class ), any (Object [].class ), anyString ()))
123+ .thenReturn (TEST_ROOM_ID );
121124
122125 // When & Then
123- CustomException exception = assertThrows (CustomException .class ,
124- () -> distributedLockAspect .lock (joinPoint , distributedLockAnnotation ));
126+ CustomException exception =
127+ assertThrows (
128+ CustomException .class ,
129+ () -> distributedLockAspect .lock (joinPoint , distributedLockAnnotation ));
125130
126131 assertAll (
127- () -> assertNotNull (exception ),
128- () -> assertEquals ("다른 요청이 작업 중입니다. 잠시 후 다시 시도해주세요." , exception .getMessage ()),
129- () -> verify (redissonClient , times (1 )).getLock (EXPECTED_LOCK_KEY ),
130- () -> verify (rLock , times (1 )).tryLock (WAIT_TIME , LEASE_TIME , TimeUnit .SECONDS ),
131- () -> verify (joinPoint , never ()).proceed (),
132- () -> verify (rLock , never ()).unlock ()
133- );
132+ () -> assertNotNull (exception ),
133+ () -> assertEquals ("다른 요청이 작업 중입니다. 잠시 후 다시 시도해주세요." , exception .getMessage ()),
134+ () -> verify (redissonClient , times (1 )).getLock (EXPECTED_LOCK_KEY ),
135+ () -> verify (rLock , times (1 )).tryLock (WAIT_TIME , LEASE_TIME , TimeUnit .SECONDS ),
136+ () -> verify (joinPoint , never ()).proceed (),
137+ () -> verify (rLock , never ()).unlock ());
134138 }
135139 }
136140
@@ -142,25 +146,30 @@ void testLock_InterruptedException() throws Throwable {
142146 when (distributedLockAnnotation .key ()).thenReturn (TEST_KEY );
143147 when (redissonClient .getLock (EXPECTED_LOCK_KEY )).thenReturn (rLock );
144148 when (rLock .tryLock (WAIT_TIME , LEASE_TIME , TimeUnit .SECONDS ))
145- .thenThrow (new InterruptedException ("Thread interrupted" ));
149+ .thenThrow (new InterruptedException ("Thread interrupted" ));
146150
147- try (MockedStatic <CustomSpringELParser > mockedParser = Mockito .mockStatic (CustomSpringELParser .class )) {
148- mockedParser .when (() -> CustomSpringELParser .getDynamicValue (
149- any (String [].class ), any (Object [].class ), anyString ()
150- )).thenReturn (TEST_ROOM_ID );
151+ try (MockedStatic <CustomSpringELParser > mockedParser =
152+ Mockito .mockStatic (CustomSpringELParser .class )) {
153+ mockedParser
154+ .when (
155+ () ->
156+ CustomSpringELParser .getDynamicValue (
157+ any (String [].class ), any (Object [].class ), anyString ()))
158+ .thenReturn (TEST_ROOM_ID );
151159
152160 // When & Then
153- InterruptedException exception = assertThrows (InterruptedException .class ,
154- () -> distributedLockAspect .lock (joinPoint , distributedLockAnnotation ));
161+ InterruptedException exception =
162+ assertThrows (
163+ InterruptedException .class ,
164+ () -> distributedLockAspect .lock (joinPoint , distributedLockAnnotation ));
155165
156166 assertAll (
157- () -> assertNotNull (exception ),
158- () -> assertEquals ("Thread interrupted" , exception .getMessage ()),
159- () -> verify (redissonClient , times (1 )).getLock (EXPECTED_LOCK_KEY ),
160- () -> verify (rLock , times (1 )).tryLock (WAIT_TIME , LEASE_TIME , TimeUnit .SECONDS ),
161- () -> verify (joinPoint , never ()).proceed (),
162- () -> verify (rLock , never ()).unlock ()
163- );
167+ () -> assertNotNull (exception ),
168+ () -> assertEquals ("Thread interrupted" , exception .getMessage ()),
169+ () -> verify (redissonClient , times (1 )).getLock (EXPECTED_LOCK_KEY ),
170+ () -> verify (rLock , times (1 )).tryLock (WAIT_TIME , LEASE_TIME , TimeUnit .SECONDS ),
171+ () -> verify (joinPoint , never ()).proceed (),
172+ () -> verify (rLock , never ()).unlock ());
164173 }
165174 }
166175
@@ -175,23 +184,27 @@ void testLock_NotHeldByCurrentThread() throws Throwable {
175184 when (rLock .isHeldByCurrentThread ()).thenReturn (false ); // 현재 스레드가 락을 보유하지 않도록 강제
176185 when (joinPoint .proceed ()).thenReturn (EXPECTED_RETURN_VALUE );
177186
178- try (MockedStatic <CustomSpringELParser > mockedParser = Mockito .mockStatic (CustomSpringELParser .class )) {
179- mockedParser .when (() -> CustomSpringELParser .getDynamicValue (
180- any (String [].class ), any (Object [].class ), anyString ()
181- )).thenReturn (TEST_ROOM_ID );
187+ try (MockedStatic <CustomSpringELParser > mockedParser =
188+ Mockito .mockStatic (CustomSpringELParser .class )) {
189+ mockedParser
190+ .when (
191+ () ->
192+ CustomSpringELParser .getDynamicValue (
193+ any (String [].class ), any (Object [].class ), anyString ()))
194+ .thenReturn (TEST_ROOM_ID );
182195
183196 // When
184197 Object result = distributedLockAspect .lock (joinPoint , distributedLockAnnotation );
185198
186199 // Then
187200 assertAll (
188- () -> assertEquals (EXPECTED_RETURN_VALUE , result ),
189- () -> verify (redissonClient , times (1 )).getLock (EXPECTED_LOCK_KEY ),
190- () -> verify (rLock , times (1 )).tryLock (WAIT_TIME , LEASE_TIME , TimeUnit .SECONDS ),
191- () -> verify (joinPoint , times (1 )).proceed (),
192- () -> verify (rLock , times (1 )).isHeldByCurrentThread (),
193- () -> verify (rLock , never ()).unlock () // unlock 호출되지 않아야 함
194- );
201+ () -> assertEquals (EXPECTED_RETURN_VALUE , result ),
202+ () -> verify (redissonClient , times (1 )).getLock (EXPECTED_LOCK_KEY ),
203+ () -> verify (rLock , times (1 )).tryLock (WAIT_TIME , LEASE_TIME , TimeUnit .SECONDS ),
204+ () -> verify (joinPoint , times (1 )).proceed (),
205+ () -> verify (rLock , times (1 )).isHeldByCurrentThread (),
206+ () -> verify (rLock , never ()).unlock () // unlock 호출되지 않아야 함
207+ );
195208 }
196209 }
197210
@@ -207,23 +220,29 @@ void testLock_ExceptionDuringExecution() throws Throwable {
207220 when (rLock .isHeldByCurrentThread ()).thenReturn (true );
208221 when (joinPoint .proceed ()).thenThrow (testException );
209222
210- try (MockedStatic <CustomSpringELParser > mockedParser = Mockito .mockStatic (CustomSpringELParser .class )) {
211- mockedParser .when (() -> CustomSpringELParser .getDynamicValue (
212- any (String [].class ), any (Object [].class ), anyString ()
213- )).thenReturn (TEST_ROOM_ID );
223+ try (MockedStatic <CustomSpringELParser > mockedParser =
224+ Mockito .mockStatic (CustomSpringELParser .class )) {
225+ mockedParser
226+ .when (
227+ () ->
228+ CustomSpringELParser .getDynamicValue (
229+ any (String [].class ), any (Object [].class ), anyString ()))
230+ .thenReturn (TEST_ROOM_ID );
214231
215232 // When & Then
216- RuntimeException exception = assertThrows (RuntimeException .class ,
217- () -> distributedLockAspect .lock (joinPoint , distributedLockAnnotation ));
233+ RuntimeException exception =
234+ assertThrows (
235+ RuntimeException .class ,
236+ () -> distributedLockAspect .lock (joinPoint , distributedLockAnnotation ));
218237
219238 assertAll (
220- () -> assertEquals (testException , exception ),
221- () -> verify (redissonClient , times (1 )).getLock (EXPECTED_LOCK_KEY ),
222- () -> verify (rLock , times (1 )).tryLock (WAIT_TIME , LEASE_TIME , TimeUnit .SECONDS ),
223- () -> verify (joinPoint , times (1 )).proceed (),
224- () -> verify (rLock , times (1 )).isHeldByCurrentThread (),
225- () -> verify (rLock , times (1 )).unlock () // 예외 발생해도 unlock 호출되어야 함
226- );
239+ () -> assertEquals (testException , exception ),
240+ () -> verify (redissonClient , times (1 )).getLock (EXPECTED_LOCK_KEY ),
241+ () -> verify (rLock , times (1 )).tryLock (WAIT_TIME , LEASE_TIME , TimeUnit .SECONDS ),
242+ () -> verify (joinPoint , times (1 )).proceed (),
243+ () -> verify (rLock , times (1 )).isHeldByCurrentThread (),
244+ () -> verify (rLock , times (1 )).unlock () // 예외 발생해도 unlock 호출되어야 함
245+ );
227246 }
228247 }
229248
@@ -237,28 +256,33 @@ void testGetLockKey_WithSpELExpression() throws Throwable {
237256
238257 when (distributedLockAnnotation .prefix ()).thenReturn ("room" );
239258 when (distributedLockAnnotation .key ()).thenReturn ("#roomId" );
240- when (methodSignature .getParameterNames ()).thenReturn (new String []{"roomId" });
241- when (joinPoint .getArgs ()).thenReturn (new Object []{roomId });
259+ when (methodSignature .getParameterNames ()).thenReturn (new String [] {"roomId" });
260+ when (joinPoint .getArgs ()).thenReturn (new Object [] {roomId });
242261
243262 when (redissonClient .getLock (expectedLockKey )).thenReturn (rLock );
244263 when (rLock .tryLock (WAIT_TIME , LEASE_TIME , TimeUnit .SECONDS )).thenReturn (true );
245264 when (rLock .isHeldByCurrentThread ()).thenReturn (true );
246265 when (joinPoint .proceed ()).thenReturn (EXPECTED_RETURN_VALUE );
247266
248- try (MockedStatic <CustomSpringELParser > mockedParser = Mockito .mockStatic (CustomSpringELParser .class )) {
249- mockedParser .when (() -> CustomSpringELParser .getDynamicValue (
250- new String []{"roomId" }, new Object []{roomId }, "#roomId"
251- )).thenReturn (roomId );
267+ try (MockedStatic <CustomSpringELParser > mockedParser =
268+ Mockito .mockStatic (CustomSpringELParser .class )) {
269+ mockedParser
270+ .when (
271+ () ->
272+ CustomSpringELParser .getDynamicValue (
273+ new String [] {"roomId" },
274+ new Object [] {roomId },
275+ "#roomId" ))
276+ .thenReturn (roomId );
252277
253278 // When
254279 Object result = distributedLockAspect .lock (joinPoint , distributedLockAnnotation );
255280
256281 // Then
257282 assertAll (
258- () -> assertEquals (EXPECTED_RETURN_VALUE , result ),
259- () -> verify (redissonClient , times (1 )).getLock (expectedLockKey ),
260- () -> verify (rLock , times (1 )).unlock ()
261- );
283+ () -> assertEquals (EXPECTED_RETURN_VALUE , result ),
284+ () -> verify (redissonClient , times (1 )).getLock (expectedLockKey ),
285+ () -> verify (rLock , times (1 )).unlock ());
262286 }
263287 }
264- }
288+ }
0 commit comments