test #439

Merged
klaus merged 7 commits from test into main 2026-07-12 14:05:39 +00:00
3 changed files with 127 additions and 0 deletions
Showing only changes of commit cd3fc00809 - Show all commits

View File

@@ -131,6 +131,7 @@ class CanCouponService(
} }
} }
@Transactional
fun useCanCoupon(couponNumber: String, memberId: Long): String { fun useCanCoupon(couponNumber: String, memberId: Long): String {
val member = memberRepository.findByIdOrNull(id = memberId) val member = memberRepository.findByIdOrNull(id = memberId)
?: throw SodaException(messageKey = "common.error.bad_credentials") ?: throw SodaException(messageKey = "common.error.bad_credentials")

View File

@@ -0,0 +1,111 @@
package kr.co.vividnext.sodalive.can.coupon
import kr.co.vividnext.sodalive.member.Member
import kr.co.vividnext.sodalive.member.MemberRepository
import kr.co.vividnext.sodalive.member.auth.Auth
import kr.co.vividnext.sodalive.support.EmbeddedRedisInitializer
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.annotation.DirtiesContext
import org.springframework.test.context.ContextConfiguration
import org.springframework.transaction.annotation.Propagation
import org.springframework.transaction.annotation.Transactional
import org.springframework.transaction.support.TransactionTemplate
import java.time.LocalDateTime
import javax.persistence.EntityManager
@SpringBootTest(
properties = [
"spring.cache.type=none",
"spring.datasource.url=jdbc:h2:mem:can-coupon-service-integration;" +
"MODE=MySQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=VALUE;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE"
]
)
@ContextConfiguration(initializers = [EmbeddedRedisInitializer::class])
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
@Transactional(propagation = Propagation.NOT_SUPPORTED)
class CanCouponServiceIntegrationTest @Autowired constructor(
private val service: CanCouponService,
private val memberRepository: MemberRepository,
private val couponNumberRepository: CanCouponNumberRepository,
private val transactionTemplate: TransactionTemplate,
private val entityManager: EntityManager
) {
@Test
@DisplayName("쿠폰 사용은 OSIV off 환경의 실제 서비스 호출 경로에서 lazy auth 접근까지 완료된다")
fun shouldUseCouponThroughTransactionalServiceProxyWhenOpenInViewIsDisabled() {
val fixture = createAuthenticatedMemberAndCouponFixture()
service.useCanCoupon(couponNumber = fixture.couponNumber, memberId = fixture.memberId)
val result = transactionTemplate.execute {
val member = memberRepository.findById(fixture.memberId).orElseThrow()
val couponNumber = couponNumberRepository.findByCouponNumber(fixture.couponNumber)!!
CouponUseResult(
rewardCan = member.pgRewardCan,
usedMemberId = couponNumber.member!!.id!!
)
}!!
assertEquals(300, result.rewardCan)
assertEquals(fixture.memberId, result.usedMemberId)
}
private fun createAuthenticatedMemberAndCouponFixture(): Fixture {
return transactionTemplate.execute {
val member = Member(
email = "can-coupon-osiv@test.com",
password = "password",
nickname = "can-coupon-osiv"
)
entityManager.persist(member)
val auth = Auth(
name = "테스트",
birth = "19900101",
uniqueCi = "can-coupon-osiv-ci",
di = "can-coupon-osiv-di",
gender = 1
)
auth.member = member
entityManager.persist(auth)
val coupon = CanCoupon(
couponName = "OSIV 회귀 테스트 쿠폰",
couponType = CouponType.CAN,
can = 300,
couponCount = 1,
validity = LocalDateTime.now().plusDays(1),
isActive = true,
isMultipleUse = false
)
entityManager.persist(coupon)
val couponNumber = CanCouponNumber("OSIVCOUPON1234")
couponNumber.canCoupon = coupon
entityManager.persist(couponNumber)
entityManager.flush()
val fixture = Fixture(
memberId = member.id!!,
couponNumber = couponNumber.couponNumber
)
entityManager.clear()
fixture
}!!
}
private data class Fixture(
val memberId: Long,
val couponNumber: String
)
private data class CouponUseResult(
val rewardCan: Int,
val usedMemberId: Long
)
}

View File

@@ -19,6 +19,7 @@ import org.mockito.Mockito.never
import org.mockito.Mockito.verify import org.mockito.Mockito.verify
import org.mockito.Mockito.`when` import org.mockito.Mockito.`when`
import org.springframework.context.ApplicationEventPublisher import org.springframework.context.ApplicationEventPublisher
import org.springframework.transaction.annotation.Transactional
import java.util.Optional import java.util.Optional
class CanCouponServiceTest { class CanCouponServiceTest {
@@ -110,6 +111,20 @@ class CanCouponServiceTest {
verify(chargeService, never()).chargeByCoupon("COUPON5678", member) verify(chargeService, never()).chargeByCoupon("COUPON5678", member)
} }
@Test
@DisplayName("쿠폰 사용은 OSIV off 환경에서도 lazy 연관을 읽을 수 있도록 트랜잭션 안에서 실행된다")
fun shouldRunUseCanCouponInTransaction() {
val method = CanCouponService::class.java.getDeclaredMethod(
"useCanCoupon",
String::class.java,
java.lang.Long.TYPE
)
val transactional = method.getAnnotation(Transactional::class.java)
assertEquals(false, transactional?.readOnly)
}
private fun createMember(memberId: Long): Member { private fun createMember(memberId: Long): Member {
return Member( return Member(
email = "member$memberId@test.com", email = "member$memberId@test.com",