강의

멘토링

로드맵

인프런 커뮤니티 질문&답변

woo님의 프로필 이미지
woo

작성한 질문수

처음 테스트 관련 에러입니다

작성

·

23

0

안녕하세요 강사님 kotlin, spring 3.x 환경에서 실습하고 있습니다

그런데 stock의 id값을 통해 생성하는 생성자를 사용하니 에러가 나고

 

val stock = Stock(1L, 100L)

 

image.png

 

val stock = Stock(100L)

이처럼 id값을 비운 상태로 재고량만 생성한 경우에는 테스트가 통과됩니다

package com.example.stock_example.service

import com.example.stock_example.domain.Stock
import com.example.stock_example.repository.StockRepository
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.TestPropertySource
import java.util.concurrent.CountDownLatch
import java.util.concurrent.Executors


@SpringBootTest
class StockServiceTest (
 @Autowired
 private val stockService: StockService,

 @Autowired
 private val stockRepository: StockRepository
){

 @BeforeEach
 fun before() {
  val stock = Stock(100L)

  stockRepository!!.saveAndFlush(stock)
 }

 @AfterEach
 fun delete() {
  stockRepository!!.deleteAll()
 }

 @Test
 fun decrease_test() {
  stockService!!.decrease(1L, 1L)

  val stock = stockRepository!!.findById(1L).orElseThrow()

  // 100 - 1 = 99
  assertEquals(99, stock.quantity)
 }
}


전체 테스트 코드는 이러합니다

언어나 버전 차이는 아닌 것 같은데, 강사님의 강의 영상에는 잘 작동하지만 제 환경에서는 변경해야 잘 작동한 점이 의아하여 질문드립니다

 

package com.example.stock_example.domain

import jakarta.persistence.Entity
import jakarta.persistence.GeneratedValue
import jakarta.persistence.GenerationType
import jakarta.persistence.Id

@Entity
class Stock (
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Long = 0,

    var productId: Long?,

    var quantity: Long
){

    constructor(id:Long, quantity: Long):this(id, null, quantity)
    constructor(quantity: Long):this(0, null, quantity)
}

혹시 몰라서 entity 클래스도 첨부합니다

답변 1

0

안녕하세요, 인프런 AI 인턴입니다.
woo님께서 겪고 계시는 문제는 StaleObjectStateException 예외로, 데이터베이스의 행이 다른 트랜잭션에 의해 업데이트되거나 삭제되는 상황에서 발생할 수 있는 Hibernate와 관련된 문제입니다.

코드를 보니 Stock 엔티티에서 @GeneratedValue(strategy = GenerationType.IDENTITY)를 사용하여 id 필드를 자동 증가하도록 설정한 것 같습니다. 이 경우 생성자의 id 값을 직접 설정하면 데이터베이스와의 동기화나 예상치 못한 충돌이 발생할 수 있습니다.

해결할 수 있는 몇 가지 방법은 다음과 같습니다:
1. 엔티티 생성 시 ID 자동 생성 기능 사용:
엔티티 객체를 생성할 때는 ID를 명시하지 않고, 데이터베이스가 자동으로 주도록 해야 합니다.

   val stock = Stock(quantity = 100L)
   stockRepository!!.save(stock)

위와 같이 작성하면, 데이터베이스에서 ID 값을 자동으로 지정해줍니다.

  1. ID 값이 필요한 경우:
    만약 특정 ID로 테스트를 하고 싶으시다면, 테스트 데이터베이스에서 그 ID 형태를 확인하고 일치시키도록 테스트 환경을 조정할 필요가 있습니다.

이미지는 [이 링크](https://cdn.inflearn.com/public/files/posts/9a43b6c6-6b1e-44c1-8f35-b7c781f93c3f/484480fb-b85a-4a25-aab0-562a166e7573.png) 을 참조하세요.

추가적으로 참고하실 수 있는 정보는 다음의 Spring Boot 문서를 참고하시기 바랍니다:
- Spring Boot Reference Documentation

문제가 해결되는데 도움이 되길 바랍니다! 추가적인 질문이 있으시면 언제든지 문의하세요.

woo님의 프로필 이미지
woo
질문자

답변 감사합니다!
그런데 강의에서 코드는 잘 동작하고 결과가 제 환경이랑 상이한 이유가 궁금합니다

woo님의 프로필 이미지
woo
질문자

해결 되었습니다!
강의 환경에서는 productId가 생성자였네요

woo님의 프로필 이미지
woo

작성한 질문수

질문하기