feat(home): 인기 커뮤니티 스냅샷 갱신 경로를 분리한다
This commit is contained in:
+54
-1
@@ -97,6 +97,57 @@ class RecommendationSnapshotFallbackServiceTest {
|
||||
Mockito.verify(lock).unlock()
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("인기 커뮤니티 fallback은 section lock을 잡고 공통 refresh 후 대상일 스냅샷을 다시 조회한다")
|
||||
fun shouldRefreshMissingPopularCommunitySnapshotsWithSectionLock() {
|
||||
val snapshotPort = FakeRecommendationFallbackSnapshotPort()
|
||||
val refreshService = Mockito.mock(RecommendationSnapshotRefreshService::class.java)
|
||||
val redissonClient = Mockito.mock(RedissonClient::class.java)
|
||||
val lock = Mockito.mock(RLock::class.java)
|
||||
val nowUtc = LocalDateTime.of(2026, 7, 9, 21, 0)
|
||||
Mockito.`when`(redissonClient.getLock(RecommendationSnapshotFallbackService.POPULAR_COMMUNITY_LOCK_KEY)).thenReturn(lock)
|
||||
Mockito.`when`(lock.tryLock(300, -1, TimeUnit.MILLISECONDS)).thenReturn(true)
|
||||
Mockito.`when`(lock.isHeldByCurrentThread).thenReturn(true)
|
||||
Mockito.doAnswer {
|
||||
snapshotPort.replaceSnapshots(
|
||||
RecommendedSectionType.POPULAR_COMMUNITY,
|
||||
LocalDateTime.of(2026, 7, 9, 14, 59, 59),
|
||||
listOf(snapshot(RecommendedSectionType.POPULAR_COMMUNITY, 7L))
|
||||
)
|
||||
1
|
||||
}.`when`(refreshService).refreshPopularCommunitySnapshots(nowUtc)
|
||||
val service = RecommendationSnapshotFallbackService(snapshotPort, refreshService, redissonClient, directExecutor())
|
||||
|
||||
val snapshots = service.refreshPopularCommunityIfMissing(offset = 0, limit = 20, nowUtc = nowUtc)
|
||||
|
||||
assertEquals(listOf(7L), snapshots.map { it.targetId })
|
||||
Mockito.verify(redissonClient).getLock(RecommendationSnapshotFallbackService.POPULAR_COMMUNITY_LOCK_KEY)
|
||||
Mockito.verify(lock).tryLock(300, -1, TimeUnit.MILLISECONDS)
|
||||
Mockito.verify(refreshService).refreshPopularCommunitySnapshots(nowUtc)
|
||||
Mockito.verify(lock).unlock()
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("인기 커뮤니티 fallback은 빈 스냅샷 marker가 있으면 refresh를 반복하지 않는다")
|
||||
fun shouldSkipPopularCommunityRefreshWhenEmptySnapshotMarkerExists() {
|
||||
val snapshotPort = FakeRecommendationFallbackSnapshotPort()
|
||||
val nowUtc = LocalDateTime.of(2026, 7, 9, 21, 0)
|
||||
snapshotPort.replaceSnapshots(
|
||||
RecommendedSectionType.POPULAR_COMMUNITY,
|
||||
LocalDateTime.of(2026, 7, 9, 14, 59, 59),
|
||||
emptyList()
|
||||
)
|
||||
val refreshService = Mockito.mock(RecommendationSnapshotRefreshService::class.java)
|
||||
val redissonClient = Mockito.mock(RedissonClient::class.java)
|
||||
val service = RecommendationSnapshotFallbackService(snapshotPort, refreshService, redissonClient, directExecutor())
|
||||
|
||||
val snapshots = service.refreshPopularCommunityIfMissing(offset = 0, limit = 20, nowUtc = nowUtc)
|
||||
|
||||
assertEquals(emptyList<RecommendationSnapshotRecord>(), snapshots)
|
||||
Mockito.verifyNoInteractions(redissonClient)
|
||||
Mockito.verifyNoInteractions(refreshService)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("응원 크리에이터 fallback은 오래된 스냅샷만 있으면 refresh를 실행한다")
|
||||
fun shouldRefreshCheerCreatorWhenOnlyStaleSnapshotsExist() {
|
||||
@@ -371,7 +422,9 @@ private class FakeRecommendationFallbackSnapshotPort : RecommendationSnapshotPor
|
||||
}
|
||||
|
||||
private fun supportsEmptySnapshotMarker(sectionType: RecommendedSectionType): Boolean {
|
||||
return sectionType == RecommendedSectionType.AI_CHARACTER || sectionType == RecommendedSectionType.CHEER_CREATOR
|
||||
return sectionType == RecommendedSectionType.AI_CHARACTER ||
|
||||
sectionType == RecommendedSectionType.CHEER_CREATOR ||
|
||||
sectionType == RecommendedSectionType.POPULAR_COMMUNITY
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+51
-22
@@ -53,8 +53,9 @@ class RecommendationSnapshotRefreshServiceTest {
|
||||
val queryPort = Mockito.mock(HomeRecommendationQueryPort::class.java)
|
||||
val service = service(snapshotPort = snapshotPort, queryPort = queryPort)
|
||||
val now = LocalDateTime.of(2026, 5, 29, 15, 0, 0)
|
||||
val snapshotAt = LocalDateTime.of(2026, 5, 29, 23, 59, 59)
|
||||
val windowStart = LocalDateTime.of(2026, 5, 23, 0, 0, 0)
|
||||
val snapshotAt = LocalDateTime.of(2026, 5, 29, 14, 59, 59)
|
||||
val windowStart = LocalDateTime.of(2026, 5, 22, 15, 0, 0)
|
||||
val windowEndExclusive = LocalDateTime.of(2026, 5, 29, 15, 0, 0)
|
||||
val aiWindowStart = LocalDateTime.of(2026, 5, 28, 15, 0, 0)
|
||||
val aiSnapshotAt = LocalDateTime.of(2026, 5, 29, 14, 59, 59)
|
||||
val aiWindowEndExclusive = LocalDateTime.of(2026, 5, 29, 15, 0, 0)
|
||||
@@ -81,7 +82,7 @@ class RecommendationSnapshotRefreshServiceTest {
|
||||
)
|
||||
)
|
||||
)
|
||||
Mockito.`when`(queryPort.findPopularCommunitySnapshots(windowStart, snapshotAt, 20)).thenReturn(
|
||||
Mockito.`when`(queryPort.findPopularCommunitySnapshots(windowStart, windowEndExclusive, 20)).thenReturn(
|
||||
listOf(
|
||||
RecommendationSnapshotRecord(
|
||||
sectionType = RecommendedSectionType.POPULAR_COMMUNITY,
|
||||
@@ -112,7 +113,7 @@ class RecommendationSnapshotRefreshServiceTest {
|
||||
|
||||
Mockito.verify(queryPort).findAiCharacterSnapshots(aiWindowStart, aiWindowEndExclusive, 20)
|
||||
Mockito.verify(queryPort).findCheerCreatorSnapshots(aiWindowStart, aiWindowEndExclusive, 16)
|
||||
Mockito.verify(queryPort).findPopularCommunitySnapshots(windowStart, snapshotAt, 20)
|
||||
Mockito.verify(queryPort).findPopularCommunitySnapshots(windowStart, windowEndExclusive, 20)
|
||||
assertEquals(true, output.out.contains("event=recommendation_snapshot_refresh_success"))
|
||||
assertEquals(true, output.out.contains("aiCharacterCount=1"))
|
||||
}
|
||||
@@ -123,8 +124,8 @@ class RecommendationSnapshotRefreshServiceTest {
|
||||
val queryPort = Mockito.mock(HomeRecommendationQueryPort::class.java)
|
||||
val service = service(queryPort = queryPort)
|
||||
val now = LocalDateTime.of(2026, 5, 29, 15, 0, 0)
|
||||
val snapshotAt = LocalDateTime.of(2026, 5, 29, 23, 59, 59)
|
||||
val windowStart = LocalDateTime.of(2026, 5, 23, 0, 0, 0)
|
||||
val windowStart = LocalDateTime.of(2026, 5, 22, 15, 0, 0)
|
||||
val windowEndExclusive = LocalDateTime.of(2026, 5, 29, 15, 0, 0)
|
||||
Mockito.`when`(
|
||||
queryPort.findAiCharacterSnapshots(
|
||||
LocalDateTime.of(2026, 5, 28, 15, 0, 0),
|
||||
@@ -139,7 +140,7 @@ class RecommendationSnapshotRefreshServiceTest {
|
||||
16
|
||||
)
|
||||
).thenReturn(emptyList())
|
||||
Mockito.`when`(queryPort.findPopularCommunitySnapshots(windowStart, snapshotAt, 20)).thenReturn(emptyList())
|
||||
Mockito.`when`(queryPort.findPopularCommunitySnapshots(windowStart, windowEndExclusive, 20)).thenReturn(emptyList())
|
||||
|
||||
TransactionSynchronizationManager.initSynchronization()
|
||||
try {
|
||||
@@ -161,8 +162,9 @@ class RecommendationSnapshotRefreshServiceTest {
|
||||
val queryPort = Mockito.mock(HomeRecommendationQueryPort::class.java)
|
||||
val service = service(snapshotPort = snapshotPort, queryPort = queryPort)
|
||||
val now = LocalDateTime.of(2026, 5, 29, 15, 0, 0)
|
||||
val snapshotAt = LocalDateTime.of(2026, 5, 29, 23, 59, 59)
|
||||
val windowStart = LocalDateTime.of(2026, 5, 23, 0, 0, 0)
|
||||
val snapshotAt = LocalDateTime.of(2026, 5, 29, 14, 59, 59)
|
||||
val windowStart = LocalDateTime.of(2026, 5, 22, 15, 0, 0)
|
||||
val windowEndExclusive = LocalDateTime.of(2026, 5, 29, 15, 0, 0)
|
||||
val aiSnapshotAt = LocalDateTime.of(2026, 5, 29, 14, 59, 59)
|
||||
val aiWindowEndExclusive = LocalDateTime.of(2026, 5, 29, 15, 0, 0)
|
||||
|
||||
@@ -184,7 +186,7 @@ class RecommendationSnapshotRefreshServiceTest {
|
||||
).thenReturn(
|
||||
listOf(snapshot(RecommendedSectionType.CHEER_CREATOR, targetId = 120L, score = 120.0, snapshotAt = snapshotAt))
|
||||
)
|
||||
Mockito.`when`(queryPort.findPopularCommunitySnapshots(windowStart, snapshotAt, 20)).thenReturn(
|
||||
Mockito.`when`(queryPort.findPopularCommunitySnapshots(windowStart, windowEndExclusive, 20)).thenReturn(
|
||||
listOf(snapshot(RecommendedSectionType.POPULAR_COMMUNITY, targetId = 225L, score = 225.0, snapshotAt = snapshotAt))
|
||||
)
|
||||
|
||||
@@ -203,16 +205,21 @@ class RecommendationSnapshotRefreshServiceTest {
|
||||
val redissonClient = Mockito.mock(RedissonClient::class.java)
|
||||
val lock = Mockito.mock(RLock::class.java)
|
||||
val cheerLock = Mockito.mock(RLock::class.java)
|
||||
val popularLock = Mockito.mock(RLock::class.java)
|
||||
val service = service(snapshotPort = snapshotPort, queryPort = queryPort, redissonClient = redissonClient)
|
||||
val now = LocalDateTime.of(2026, 5, 29, 15, 0, 0)
|
||||
val snapshotAt = LocalDateTime.of(2026, 5, 29, 23, 59, 59)
|
||||
val windowStart = LocalDateTime.of(2026, 5, 23, 0, 0, 0)
|
||||
val windowStart = LocalDateTime.of(2026, 5, 22, 15, 0, 0)
|
||||
val windowEndExclusive = LocalDateTime.of(2026, 5, 29, 15, 0, 0)
|
||||
Mockito.`when`(redissonClient.getLock(RecommendationSnapshotFallbackService.AI_CHARACTER_LOCK_KEY)).thenReturn(lock)
|
||||
Mockito.`when`(redissonClient.getLock(RecommendationSnapshotFallbackService.CHEER_CREATOR_LOCK_KEY)).thenReturn(cheerLock)
|
||||
Mockito.`when`(redissonClient.getLock(RecommendationSnapshotFallbackService.POPULAR_COMMUNITY_LOCK_KEY))
|
||||
.thenReturn(popularLock)
|
||||
Mockito.`when`(lock.tryLock(0, -1, TimeUnit.MILLISECONDS)).thenReturn(true)
|
||||
Mockito.`when`(lock.isHeldByCurrentThread).thenReturn(true)
|
||||
Mockito.`when`(cheerLock.tryLock(0, -1, TimeUnit.MILLISECONDS)).thenReturn(true)
|
||||
Mockito.`when`(cheerLock.isHeldByCurrentThread).thenReturn(true)
|
||||
Mockito.`when`(popularLock.tryLock(0, -1, TimeUnit.MILLISECONDS)).thenReturn(true)
|
||||
Mockito.`when`(popularLock.isHeldByCurrentThread).thenReturn(true)
|
||||
Mockito.`when`(
|
||||
queryPort.findAiCharacterSnapshots(
|
||||
LocalDateTime.of(2026, 5, 28, 15, 0, 0),
|
||||
@@ -227,7 +234,7 @@ class RecommendationSnapshotRefreshServiceTest {
|
||||
16
|
||||
)
|
||||
).thenReturn(emptyList())
|
||||
Mockito.`when`(queryPort.findPopularCommunitySnapshots(windowStart, snapshotAt, 20)).thenReturn(emptyList())
|
||||
Mockito.`when`(queryPort.findPopularCommunitySnapshots(windowStart, windowEndExclusive, 20)).thenReturn(emptyList())
|
||||
|
||||
service.refreshDailySnapshots(now)
|
||||
|
||||
@@ -240,6 +247,7 @@ class RecommendationSnapshotRefreshServiceTest {
|
||||
)
|
||||
Mockito.verify(lock).unlock()
|
||||
Mockito.verify(cheerLock).unlock()
|
||||
Mockito.verify(popularLock).unlock()
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -250,22 +258,28 @@ class RecommendationSnapshotRefreshServiceTest {
|
||||
val redissonClient = Mockito.mock(RedissonClient::class.java)
|
||||
val aiLock = Mockito.mock(RLock::class.java)
|
||||
val cheerLock = Mockito.mock(RLock::class.java)
|
||||
val popularLock = Mockito.mock(RLock::class.java)
|
||||
val service = service(snapshotPort = snapshotPort, queryPort = queryPort, redissonClient = redissonClient)
|
||||
val now = LocalDateTime.of(2026, 5, 29, 15, 0, 0)
|
||||
val windowStart = LocalDateTime.of(2026, 5, 23, 0, 0, 0)
|
||||
val snapshotAt = LocalDateTime.of(2026, 5, 29, 23, 59, 59)
|
||||
val windowStart = LocalDateTime.of(2026, 5, 22, 15, 0, 0)
|
||||
val windowEndExclusive = LocalDateTime.of(2026, 5, 29, 15, 0, 0)
|
||||
val snapshotAt = LocalDateTime.of(2026, 5, 29, 14, 59, 59)
|
||||
val cheerWindowStart = LocalDateTime.of(2026, 5, 28, 15, 0, 0)
|
||||
val cheerWindowEndExclusive = LocalDateTime.of(2026, 5, 29, 15, 0, 0)
|
||||
Mockito.`when`(redissonClient.getLock(RecommendationSnapshotFallbackService.AI_CHARACTER_LOCK_KEY)).thenReturn(aiLock)
|
||||
Mockito.`when`(redissonClient.getLock(RecommendationSnapshotFallbackService.CHEER_CREATOR_LOCK_KEY)).thenReturn(cheerLock)
|
||||
Mockito.`when`(redissonClient.getLock(RecommendationSnapshotFallbackService.POPULAR_COMMUNITY_LOCK_KEY))
|
||||
.thenReturn(popularLock)
|
||||
Mockito.`when`(aiLock.tryLock(0, -1, TimeUnit.MILLISECONDS)).thenReturn(false)
|
||||
Mockito.`when`(aiLock.isHeldByCurrentThread).thenReturn(false)
|
||||
Mockito.`when`(cheerLock.tryLock(0, -1, TimeUnit.MILLISECONDS)).thenReturn(true)
|
||||
Mockito.`when`(cheerLock.isHeldByCurrentThread).thenReturn(true)
|
||||
Mockito.`when`(popularLock.tryLock(0, -1, TimeUnit.MILLISECONDS)).thenReturn(true)
|
||||
Mockito.`when`(popularLock.isHeldByCurrentThread).thenReturn(true)
|
||||
Mockito.`when`(queryPort.findCheerCreatorSnapshots(cheerWindowStart, cheerWindowEndExclusive, 16)).thenReturn(
|
||||
listOf(snapshot(RecommendedSectionType.CHEER_CREATOR, targetId = 10L, score = 10.0, snapshotAt = snapshotAt))
|
||||
)
|
||||
Mockito.`when`(queryPort.findPopularCommunitySnapshots(windowStart, snapshotAt, 20)).thenReturn(emptyList())
|
||||
Mockito.`when`(queryPort.findPopularCommunitySnapshots(windowStart, windowEndExclusive, 20)).thenReturn(emptyList())
|
||||
|
||||
service.refreshDailySnapshots(now)
|
||||
|
||||
@@ -274,6 +288,7 @@ class RecommendationSnapshotRefreshServiceTest {
|
||||
Mockito.verify(queryPort).findCheerCreatorSnapshots(cheerWindowStart, cheerWindowEndExclusive, 16)
|
||||
assertEquals(listOf(10L), snapshotPort.findLatestSnapshots(RecommendedSectionType.CHEER_CREATOR).map { it.targetId })
|
||||
Mockito.verify(cheerLock).unlock()
|
||||
Mockito.verify(popularLock).unlock()
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -284,17 +299,23 @@ class RecommendationSnapshotRefreshServiceTest {
|
||||
val redissonClient = Mockito.mock(RedissonClient::class.java)
|
||||
val aiLock = Mockito.mock(RLock::class.java)
|
||||
val cheerLock = Mockito.mock(RLock::class.java)
|
||||
val popularLock = Mockito.mock(RLock::class.java)
|
||||
val service = service(snapshotPort = snapshotPort, queryPort = queryPort, redissonClient = redissonClient)
|
||||
val now = LocalDateTime.of(2026, 5, 29, 15, 0, 0)
|
||||
val snapshotAt = LocalDateTime.of(2026, 5, 29, 23, 59, 59)
|
||||
val windowStart = LocalDateTime.of(2026, 5, 23, 0, 0, 0)
|
||||
val snapshotAt = LocalDateTime.of(2026, 5, 29, 14, 59, 59)
|
||||
val windowStart = LocalDateTime.of(2026, 5, 22, 15, 0, 0)
|
||||
val windowEndExclusive = LocalDateTime.of(2026, 5, 29, 15, 0, 0)
|
||||
Mockito.`when`(redissonClient.getLock(RecommendationSnapshotFallbackService.AI_CHARACTER_LOCK_KEY)).thenReturn(aiLock)
|
||||
Mockito.`when`(redissonClient.getLock(RecommendationSnapshotFallbackService.CHEER_CREATOR_LOCK_KEY)).thenReturn(cheerLock)
|
||||
Mockito.`when`(redissonClient.getLock(RecommendationSnapshotFallbackService.POPULAR_COMMUNITY_LOCK_KEY))
|
||||
.thenReturn(popularLock)
|
||||
Mockito.`when`(aiLock.tryLock(0, -1, TimeUnit.MILLISECONDS)).thenReturn(false)
|
||||
Mockito.`when`(aiLock.isHeldByCurrentThread).thenReturn(false)
|
||||
Mockito.`when`(cheerLock.tryLock(0, -1, TimeUnit.MILLISECONDS)).thenReturn(false)
|
||||
Mockito.`when`(cheerLock.isHeldByCurrentThread).thenReturn(false)
|
||||
Mockito.`when`(queryPort.findPopularCommunitySnapshots(windowStart, snapshotAt, 20)).thenReturn(
|
||||
Mockito.`when`(popularLock.tryLock(0, -1, TimeUnit.MILLISECONDS)).thenReturn(true)
|
||||
Mockito.`when`(popularLock.isHeldByCurrentThread).thenReturn(true)
|
||||
Mockito.`when`(queryPort.findPopularCommunitySnapshots(windowStart, windowEndExclusive, 20)).thenReturn(
|
||||
listOf(snapshot(RecommendedSectionType.POPULAR_COMMUNITY, targetId = 20L, score = 20.0, snapshotAt = snapshotAt))
|
||||
)
|
||||
|
||||
@@ -311,6 +332,7 @@ class RecommendationSnapshotRefreshServiceTest {
|
||||
)
|
||||
assertEquals(listOf(20L), snapshotPort.findLatestSnapshots(RecommendedSectionType.POPULAR_COMMUNITY).map { it.targetId })
|
||||
Mockito.verify(cheerLock, Mockito.never()).unlock()
|
||||
Mockito.verify(popularLock).unlock()
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -321,16 +343,22 @@ class RecommendationSnapshotRefreshServiceTest {
|
||||
val redissonClient = Mockito.mock(RedissonClient::class.java)
|
||||
val lock = Mockito.mock(RLock::class.java)
|
||||
val cheerLock = Mockito.mock(RLock::class.java)
|
||||
val popularLock = Mockito.mock(RLock::class.java)
|
||||
val service = service(snapshotPort = snapshotPort, queryPort = queryPort, redissonClient = redissonClient)
|
||||
val now = LocalDateTime.of(2026, 5, 29, 15, 0, 0)
|
||||
val snapshotAt = LocalDateTime.of(2026, 5, 29, 23, 59, 59)
|
||||
val windowStart = LocalDateTime.of(2026, 5, 23, 0, 0, 0)
|
||||
val snapshotAt = LocalDateTime.of(2026, 5, 29, 14, 59, 59)
|
||||
val windowStart = LocalDateTime.of(2026, 5, 22, 15, 0, 0)
|
||||
val windowEndExclusive = LocalDateTime.of(2026, 5, 29, 15, 0, 0)
|
||||
Mockito.`when`(redissonClient.getLock(RecommendationSnapshotFallbackService.AI_CHARACTER_LOCK_KEY)).thenReturn(lock)
|
||||
Mockito.`when`(redissonClient.getLock(RecommendationSnapshotFallbackService.CHEER_CREATOR_LOCK_KEY)).thenReturn(cheerLock)
|
||||
Mockito.`when`(redissonClient.getLock(RecommendationSnapshotFallbackService.POPULAR_COMMUNITY_LOCK_KEY))
|
||||
.thenReturn(popularLock)
|
||||
Mockito.`when`(lock.tryLock(0, -1, TimeUnit.MILLISECONDS)).thenReturn(false)
|
||||
Mockito.`when`(lock.isHeldByCurrentThread).thenReturn(false)
|
||||
Mockito.`when`(cheerLock.tryLock(0, -1, TimeUnit.MILLISECONDS)).thenReturn(true)
|
||||
Mockito.`when`(cheerLock.isHeldByCurrentThread).thenReturn(true)
|
||||
Mockito.`when`(popularLock.tryLock(0, -1, TimeUnit.MILLISECONDS)).thenReturn(true)
|
||||
Mockito.`when`(popularLock.isHeldByCurrentThread).thenReturn(true)
|
||||
Mockito.`when`(
|
||||
queryPort.findCheerCreatorSnapshots(
|
||||
LocalDateTime.of(2026, 5, 28, 15, 0, 0),
|
||||
@@ -340,7 +368,7 @@ class RecommendationSnapshotRefreshServiceTest {
|
||||
).thenReturn(
|
||||
listOf(snapshot(RecommendedSectionType.CHEER_CREATOR, targetId = 1L, score = 1.0, snapshotAt = snapshotAt))
|
||||
)
|
||||
Mockito.`when`(queryPort.findPopularCommunitySnapshots(windowStart, snapshotAt, 20)).thenReturn(emptyList())
|
||||
Mockito.`when`(queryPort.findPopularCommunitySnapshots(windowStart, windowEndExclusive, 20)).thenReturn(emptyList())
|
||||
|
||||
service.refreshDailySnapshots(now)
|
||||
|
||||
@@ -356,6 +384,7 @@ class RecommendationSnapshotRefreshServiceTest {
|
||||
assertEquals(listOf(1L), snapshotPort.findLatestSnapshots(RecommendedSectionType.CHEER_CREATOR).map { it.targetId })
|
||||
Mockito.verify(lock, Mockito.never()).unlock()
|
||||
Mockito.verify(cheerLock).unlock()
|
||||
Mockito.verify(popularLock).unlock()
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user