묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결더 자바, 애플리케이션을 테스트하는 다양한 방법
Testcontainers ddl-auto 동작 시점
spring boot, jpa, junit5, testcontainers를 이용해서 테스트 코드를 작성하고 있습니다.총 12개의 테스트 클래스를 만들었고 각 클래스마다 testcontainers 객체를 static으로 가지고 있고 모두 @SpringBootTest, @Testcontainers 어노테이션만 추가했습니다.(Controller 테스트 시 @AutoConfigureMockMvc 어노테이션 추가)jpa의 ddl-auto 값을 create-drop으로 설정했기 때문에 gradle test를 실행할 때 예상되는 결과는 각 클래스를 테스트할 때마다 테이블이 새로 생성되어야 할 것 같은데 실제로는 총 2번 생성됩니다.각 클래스마다 Testcontainers를 적용했음에도 불구하고 실패한 로그를 보면 이전 클래스에서 사용한 데이터를 다음 클래스에서도 사용하는 것처럼 보이는데 테스트 실행 시 각 테스트 클래스마다 jpa의 ddl-auto 속성이 동작하지 않는 이유각 클래스에 Testcontainers를 적용했음에도 불구하고 생성된 데이터베이스가 컨테이너들이 공유하는 이유가 궁금합니다.
-
미해결더 자바, 애플리케이션을 테스트하는 다양한 방법
testcontainers DB 공유 이슈
junit5, jpa를 이용해서 테스트 코드를 작성하고 testcontainers를 이용해서 테스트를 수행하려고 합니다.A entity는 n개의 B entity를 가지고 있고, B entity는 C entity를 가지고 있습니다.A에 관련된 테스트 클래스, B에 관련된 테스트 클래스(A entity 이용), C에 관련된 테스트 클래스(A, B entity 모두 이용)를 클래스별로 각각 테스트를 진행하면 모두 정상적으로 통과합니다. 하지만 gradle test로 전체 클래스에 대해서 테스트를 진행하면 종종 실패합니다.로그를 확인했는데 C 클래스를 테스트하면서 db에 A, B, C 데이터가 insert됐고 이어서 B 클래스를 테스트할 때 @BeforeAll로 B, A 순서로 데이터를 삭제하는 과정에서 C 데이터가 남아있기 때문에 B 데이터를 삭제할 수 없어 테스트가 실패합니다. 이해하기로는 testcontainers가 각 클래스에서 static으로 선언되면 테스트 시작 시점에 컨테이너가 생성되어 순수한 상태의 db로 테스트를 진행할 수 있고 테스트가 끝나면 컨테이너가 삭제되어 db도 자연스럽게 초기화된다고 생각했는데실제로는 하나의 db를 여러 개의 container가 공유해서 사용하는 것처럼 보입니다. 컨테이너 생성이 db의 생명주기에 영향을 주나요?
-
미해결쥬쥬와 함께 하루만에 끝내는 스프링 테스트
강의를 수강하면서 2가지 질문이 생겼습니다
안녕하세요 쥬쥬님의 강의를 보면서 테스트 코드 작성에 도움을 많이 받고 있습니다. 감사합니다. 질문이 있어서 글을 올려드립니다. 질문1.application.yml 에서 mysql, redis, kafka 의 호스트를 컨테이너 이름으로 지정해주면 굳이 IntegrationTestInitializer 정적 클래스의 initialize() 메서드를 구현해 동적으로 호스트와 아이피를 지정할 필요가 없을 것이라고 생각했습니다. 왜 application.yml 에서 각 모듈의 호스트를 localhost 로 지정해주셨는지 여쭤보고 싶습니다. 질문2.redis, kafka 에 특화된 테스트 컨테이너 모듈을 사용하셨는데, 이러한 모듈을 사용하지 않고 그냥 testImplementation "org.testcontainers:testcontainers:1.19.0" 만을 사용해서 테스트 컨테이너를 구동시켜 테스트해도 되는지 여쭤보고 싶습니다. 예를 들어 이런 식으로 입니다. 질문 읽어주셔서 감사합니다.
-
미해결재고시스템으로 알아보는 동시성이슈 해결방법
Pessimistic Lock 전체 테스트 오류 문의
안녕하세요. Pessimistic Lock 소스에서 각각의 테스트 하나하나는 통과하는데요. 테스트 코드 전체로 돌리면 에러가 나더라고요. public interface StockRepository extends JpaRepository<Stock, Long> { @Lock(LockModeType.PESSIMISTIC_WRITE) @Query("select s from Stock s where s.id = :id") Stock findByIdWithPessimisticLock(@Param("id") Long id); } StockServiceTest.javapackage com.example.stock.service; import com.example.stock.domain.Stock; import com.example.stock.repository.StockRepository; import org.junit.jupiter.api.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest class StockServiceTest { @Autowired private PessimisticLockStockService stockService; @Autowired private StockRepository stockRepository; @BeforeEach public void before() { stockRepository.saveAndFlush(new Stock(1L, 100L)); } @AfterEach public void after() { stockRepository.deleteAll(); } @Test @DisplayName("재고1개 감소 테스트") public void 재고감소() { stockService.decrease(1L, 1L); //100 - 1 = 99 Stock stock = stockRepository.findById(1L).orElseThrow(); assertThat(stock.getQuantity()).isEqualTo(99L); } @Test @DisplayName("동시에 100개 요청 테스트") public void 동시에_100개_요청() throws InterruptedException { int threadCount = 100; ExecutorService executorService = Executors.newFixedThreadPool(32); CountDownLatch countDownLatch = new CountDownLatch(threadCount); for (int i = 0; i < threadCount; i++) { executorService.submit(() -> { try { stockService.decrease(1L, 1L); } finally { countDownLatch.countDown(); } }); } countDownLatch.await(); Stock stock = stockRepository.findById(1L).orElseThrow(); assertThat(stock.getQuantity()).isEqualTo(0L); } } 이런 오류가 나는데 @BeforeEach에서 새로 등록하고 @AfterEach에서 delete를 해줘서 각각의 테스트에 영향이 없을거 같은데 왜 나는지 잘 모르겠어요 ㅠ github : https://github.com/nhs0912/stock
-
미해결스프링부트 JUnit 테스트 - 시큐리티를 활용한 Bank 애플리케이션
안녕하세요 인증이 필요한 url을 위하여 /s를 붙이는것에 대해 질문있습니다.
안녕하세요 인증이 필요한 url을 위하여 /s를 붙이는것에 대해 질문있습니다.실무에서도 url분리를 위해 /s만 붙이기도 하나요?아니라면 url 설계를 어떤식으로 해야할지 팁을 알고싶습니당.
-
미해결스프링부트 JUnit 테스트 - 시큐리티를 활용한 Bank 애플리케이션
validation aop사용에 대해서 질문있습니다.
@ResponseStatus(HttpStatus.BAD_REQUEST)@ExceptionHandler(BindException.class)public ApiResponse<Object> bindException(BindException e) {이런식으로 전역적으로 validation을 해주면 aop를 사용하지 않고 더 편하고 어노테이션도 안달아줘도 될거같은데 aop를 사용하면 장점이 무엇인가요?
-
미해결쥬쥬와 함께 하루만에 끝내는 스프링 테스트
github action
좋은 강의 너무 잘 들었습니다.그런데 github action 파일에서 jdk 설치는 왜 필요한 것일까요?그리고 jdk 설치 등 job의 실행 주체는 github action 이라는 깃허브 repository 내장된 서버라고 보면 될까요?감사합니다.
-
미해결쥬쥬와 함께 하루만에 끝내는 스프링 테스트
Model 의존 java.lang, jakarta
좋은 강의 잘 듣고 있습니다.<의존성 검증: Controller는 Entity를 사용하고 있을까?> 강의에서요.11:40초 쯤에서 에러 로그들이 의미하는 것이 궁금합니다.Class <com.jyujyu.dayonetest.model.StudentFail> is annotated with <jakarta.persistence.Entity> Class <com.jyujyu.dayonetest.model.StudentPass> extends class <java.lang.Object>..위 같은 에러는 해당 모델들(StudentFail, StudentPass) 이 @Entity 로 정의되었으므로 jakarta.persistence.Entity, jakarta.persistence.Table> 에서 사용된 것은 알겠는데java.lang.Object 로 사용된 것은 어떻게 봐야 하나요?단순 Object 라면, 모든 클래스는 Object 를 의존하는 것 아닌가요?미리 답변 감사합니다!
-
미해결Kotlin으로 개발하는 Spring Boot Web MVC
[제발 부탁 드립니다.]react와 스프링 부트간 통신하는데 통신이 안되네요. 무엇이 문제일까요??
=========중용한 부분이 오타가 있어서 수정합니다================ 안녕하세요. 완강을 한후에 제가 프론트엔드와 백엔드간 통신을 확인하려합니다. 그런데 예상과 다르네요...일단 프론트 엔드 (react을 먼저 보여드릴께요) const handleSubmit = (event) => { fetch('http://localhost:8080/api/posttest', { method: 'POST', // *GET, POST, PUT, DELETE 등 body: JSON.stringify({ name: 'foo', email: 'kjy@gmail.com', message: '1', }), headers: { 'Content-type': 'application/json; charset=UTF-8', }, }) .then((response) => response.json()) .then((json) => alert(json)); alert("test") };이렇게 작성하고 ...백엔드( spring boot)는@RestController @RequestMapping("/api") class _____ApiController{ @PostMapping(path=["/posttest"]) fun postTest( @RequestBody body: BodyClass ): ResponseEntity<String> { println(body) return ResponseEntity.ok().body("test") } }data class BodyClass( var name: String = "", var email: String = "", var message: String = "" ) 이렇게 코딩 했는데 ..분명해서 테스트 해서 정상 확인했는데 ...react에서 전송하면 postTest 함수를 진입하지 않습니다. ... 백엔드쪽에 코드를 좀 바꿔서 Requestbody에서 json 파일 그대로 받자는 식으로 아래처럼 바꿨어요fun postTest( @RequestBody json: String ): ResponseEntity<String> { println(body) return ResponseEntity.ok().body("test") } react는 json 형식인지 표시하는걸 지웠는데fetch('http://localhost:8080/api/posttest', { method: 'POST', // *GET, POST, PUT, DELETE 등 body: JSON.stringify({ name: 'foo', email: 'kjy@gmail.com', message: '1', }), headers: { // 삭제 }, }) .then((response) => response.json()) .then((json) => alert(json)); alert("test" 백엔드의 postTest함수에 진입 합니다.프론트 엔드에서 전송한 json 내네요용이 전송됩니다.이게 ... 새롭게 프로젝트를 만들어도 똑같고 프론트 엔드 백엔드 모두 새롭게 프로젝트를 만들어서 테스트 해도 똑같아요...스프링 부트에서 잘못된건지... react에서 잘못된건지 잘 모르겠네요...아마도 스프링 부트에서 뭔가 잘못된거 같은게 api 서버가 있어서 그걸로 접속하니깐 되긴 하네요...그렇다면 스프링 부트에서 잘못한건지..분명 스프링 부트에도 문제가 없어 보이는데힘드네요 ... ㅠ.ㅠ 살려주세요 ㅠ.ㅠ 몇일째 못풀고 있어요...
-
미해결쥬쥬와 함께 하루만에 끝내는 스프링 테스트
put api 500 서버에러응답 문제
선생님 안녕하세요 두번째 강의 막 시작했는데요...^^강의 아주 초반에는 postman으로 성적저장 put api 보낼 때는 스프링 서버가 잘 응답했는데, 오히려성적저장 애플리케이션 개발 후 마지막으로 테스트 put api 보낼때는 응답못하고 500 에러 뱉으면서 local host access denied 이런 에러가 갑자기 나오는데 구글링하고 chatGPT 물어봐도 해결이 안 되요. 아무래도 db쪽 문제인 것 같은데 뭐가 문제일까요? 도와주세요.
-
미해결쥬쥬와 함께 하루만에 끝내는 스프링 테스트
스프링 버전
안녕하세요.수업 잘 듣고 있는 수강생입니다.별개로 회사에서 스프링버전 1버전도 있고 2버전도 있는데요, 그런 경우는 junit5 라이브러리를 따로 임포트 해서 사용하지 못할까요?
-
미해결더 자바, 애플리케이션을 테스트하는 다양한 방법
질문있습니다.
현재 스프링부트는 3.x버전대인데..버전대 맞춰서 예제나 소스코드를 변경해야할까요?..강의버전대는 2.1? 버전으로 알고있습니다..(지원하지 않은 코드가 있을경우)아울러 9월 이후로 답변주시지 않으신것같은데..질문이나 답변은 더 이상 안하시는것일까요?
-
미해결스프링부트 JUnit 테스트 - 시큐리티를 활용한 Bank 애플리케이션
Dummy 클래스 위치에 대한 질문
현재 "회원가입 서비스 코드 리팩토링"까지 봤는데 Dummy는 테스트 단에서만 쓰이는 것으로 보입니다. 그러면 더미 클래스를 main.config.dummy가 아닌 test.dummy에 작성하는 것이 의미가 분명하고 추후 개발 및 배포에서도 용이한 것 아닌지 의문이 들어 질문 드립니다! config에 작성한 이유와 test에 작성하지 않은 이유가 궁금합니다.!
-
미해결스프링부트 JUnit 테스트 - 시큐리티를 활용한 Bank 애플리케이션
테스트 방식에 관해서 질문이 있어요
안녕하세요 강사님 강의 듣고 많이 배우고 있습니다.다름이 아니라 테스트 방식에 질문이 있어서 문의 드립니다.현재 테스트는 서비스 코드를 먼저 짜고 테스트를 진행하는데테스트 방식에는 테스트 코드를 먼저 짜고 서비스 코드를 만들어가는 형식도 있더라구요..둘 차이점이 혹시 있을까요..
-
미해결쥬쥬와 함께 하루만에 끝내는 스프링 테스트
flyway 컨테이너가 동작하지 않습니다.
안녕하세요! 강의 잘 듣고 있는 중에 문의드립니다.현재 컨테이너 기반 테스트 환경을 구성한 상태로, 실제 데이터로 테스트를 진행하기에 앞서 맥북으로 진행하던 내용을 pc에서도 진행하고자 코드를 그대로 pull해온 상태입니다. 근데 컨테이너들이 정상적으로 동작하는 것 같지 않아 문의드립니다...ㅠ스프링 로그에서는 마이그레이션 성공시 출력될 로그를 확인하는 정규식 표현에 매칭되는 로그를 찾지 못해 timeout이 나는 것으로 나오고, 도커 데스크탑을 보고 있으면 다른 컨테이너들은 정상적으로 실행되는데에 반해 flyway 컨테이너(local-db-migrate)만 계속 Exited와 Restart를 반복하고 있습니다. 해당 컨테이너 로그를 살펴보면 계속해서 아래와 같이 출력됩니다 ㅠㅠ /flyway/conf/flyway.conf는 컨테이너의 볼륨에서 해당 파일을 찾지 못했다는 것인가요? 혹시 해결 방안을 아시면 답변 부탁드리겠습니다. 참고로 OS는 윈도우입니다.infra/test/docker-compose.yaml 파일db/flyway.conf 파일
-
해결됨쥬쥬와 함께 하루만에 끝내는 스프링 테스트
Mock 객체 사용법
아직 mock 사용법이 이해가 안가는데 실제로 db에 저장도 안되고 jpa repository 호출도 안되는 건가요? db가 올라간 도커를 내려도 잘 되네요
-
미해결쥬쥬와 함께 하루만에 끝내는 스프링 테스트
flyway jdbcdriver 오류
https://www.inflearn.com/questions/1199599/m1-mac-도커-컴포즈-docker-compose-up-에러안녕하세요 이전에 docker-compose에서 flyway를 띄울 때 오류가 있어 질문을 드렸습니다.말씀해주신대로 버전을 변경해서 실행을 하니 해당 오류는 발생하지 않으나 다른 에러가 발생하였습니다.ERROR: Unable to instantiate JDBC driver: com.mysql.cj.jdbc.Driver => Check whether the jar file is presentCaused by: Unable to instantiate class com.mysql.cj.jdbc.Driver : com.mysql.cj.jdbc.DriverCaused by: java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver 나름대로 구글링해본 결과 직접 jdbc 파일을 넣어주어야 한다고 하는데 이렇게 하는게 맞을까요?flyway의 github에 들어가서 compose 파일을 확인하니 alphine 리눅스로 되어 있던데 jdbc driver jar파일을 다운받으려고 사이트를 들어가니 알파인 리눅스용 드라이버는 없던데 어떻게 해야할까요? 강사님으로부터 flyway를 처음 알게되었는데 유용할 것 같아 넘어갈 수 있는 부분이지만 다시 질문드리게 되었습니다. 감사합니다.
-
미해결쥬쥬와 함께 하루만에 끝내는 스프링 테스트
강의 코드
안녕하세요 강사님 강의를 거의 다 들어가고 있는 시점인데...제공해주신 노션 자료는 너무 좋은데요.. 코드나 커밋된 git 주소 좀 알려주실 수 있나요?노션 자료가 좋긴한데 코드가 없어서 개인적으로 조금 힘드네요
-
미해결스프링부트 JUnit 테스트 - 시큐리티를 활용한 Bank 애플리케이션
스프링 버전업일 경우에는 Pointcut @PostMapping 조건이 달라질까요?
안녕하세요 강사님현재 스프링부트 3.2.2 버전을 사용하고 있습니다.배운대로 개인적인 프로젝트에 적용해보고 있는데@Around 애노테이션의 메서드 실행이@GetMapping일 경우에는 AOP가 잘 작동하나@PostMapping일 경우에는 작동하지 않고@Validation 애노테이션에서 오류가 먼저 터집니다..무슨 문제일까요..? .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public org.springframework.http.ResponseEntity<?> com.board.www.app.board.controller.api.BoardApiController.create(com.board.www.app.board.dto.BoardDto,org.springframework.web.multipart.MultipartFile) with 2 errors: [Field error in object 'dto' on field 'content': rejected value []; codes [NotBlank.dto.content,NotBlank.content,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [dto.content,content]; arguments []; default message [content]]; default message [내용을 입력해 주세요]] [Field error in object 'dto' on field 'title': rejected value []; codes [NotBlank.dto.title,NotBlank.title,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [dto.title,title]; arguments []; default message [title]]; default message [제목을 입력해 주세요]] ]
-
미해결쥬쥬와 함께 하루만에 끝내는 스프링 테스트
[M1 MAC] 도커 컴포즈 docker-compose up 에러
docker compose up -d[+] Building 0.0s (0/0) docker:desktop-linux[+] Running 4/4 ✔ Network local_default Created 0.0s ✔ Container local-local-db-1 Started 0.1s ✔ Container local-local-db-migrate-1 Started 0.1s ! local-db-migrate The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested 0.0s 안녕하세요 강의 잘 듣고 있습니다. 강사님께서 주신 설정 파일을 토대로 동일하게 복사, 붙여넣기를 하고 경로도 동일하게 했는데 위와 같은 에러가 나오고 있습니다. DB에 접속은 되는데 안에 초기 데이터가 들어가지를 않는데 어떤게 문제이고 어떻게 해결할 수 있을까요?