묻고 답해요
156만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결Spring Boot TDD - 입문부터 실전까지 정확하게
30. 누락된 테스트 시나리오 발견
"이 간단한 정규식을 사용하면 지금까지 테스트는 모두 통과할 것 같긴 한데 사용자 이름 정책에서 허용되지 않은 문자들은 걸러지겠지만 허용이 되는 문자들이 정규식에 반영되지는 않습니다"-> 그렇기 때문에 기존 테스트는 유지하면서 새로운 테스트케이스를 추가한다로 진행이된다.부분에서 추가되는것이 이해가 안되어 질문드립니다.이전 "email속성이 올바른 형식을 따르지 않으면 400 상태코드를 반환" 에선 누락된 부분을 기능을 수정하는 방식으로 해결해왔는데 왜 "username 속성이 올바르지 않은 형식을 따르지 않으면" 에서도 테스트케이스 추가가아닌 기능을 수정해서 해결해야하는것 아닌가?또 기존의 "올바르게 요청하면 204 반환" 의 케이스와 의미가겹쳐 중복된 테스트케이스 추가 즉 잘못된 케이스추가가 아닌가? 라고 생각됩니다 어떻게 생각하시는지 여쭤보고싶습니다!초반부이지만 최고의강의 잘듣고있습니다. 감사합니다
-
해결됨Spring Boot TDD - 입문부터 실전까지 정확하게
69.테스트격리 / 과도한 테스트 격리의 문제 중 '부적절한 설계 왜곡'
강의: 섹션 14 - 69. 테스트 격리 과도한 테스트 격리의 문제점 중 '부적절한 설계 왜곡'의 예시로1) new 연산자로 직접 만들어도 좋은 클래스 인스턴스를 굳이 주입, 2) 클래스 의존을 인터페이스 의존으로 변경, 3) private을 public으로 변경을 들어주셨는데 다음과 같은 상황을 말씀하시는게 맞는지 궁금합니다. 1) new 연산자로 직접 만들어도 좋은 클래스 인스턴스를 굳이 주입 & 2) 클래스 의존을 인터페이스 의존으로 변경: 테스트 대상을 완벽히 격리하기 위해 '단순하거나 변경 가능성 없이 구현체가 하나뿐인 의존 클래스'도 직접 생성 대신 주입받도록 변경해 mock으로 대체함.3) private을 public으로 변경: 다른 기능들에서 사용되는 private 메서드를 단독으로 테스트하기 위해 public으로 노출시킴.강의 잘 듣고 있습니다. 감사합니다.
-
미해결Spring Boot TDD - 입문부터 실전까지 정확하게
"오해: 단위 테스트와 통합 테스트를 잘 분리해야한다." 에 대한 질문
안녕하세요. 강의를 듣다 아래와 같은 내용에 대해 개인적인 생각이 있고, 이 생각에 대해 강사님의 생각이 궁금하여 질문 글 올립니다. "오해: 단위 테스트와 통합 테스트를 잘 분리해야한다." 저 또한, 단위 테스트와 통합 테스트를 분명하게 구분하기에는 모호한 부분이 있다고 생각합니다. 하지만, 저는 이를 분리해서 테스트를 진행하고자 합니다.명확한 합의는 없으나, 팀 내 혹은 저에게 있어 단위 테스트와 통합 테스트를 아래와 같이 구분하고자 했습니다.단위 테스트 : 외부의 영향이 존재 하지 않고 가장 작은 단위로써 해당 부분 내에서만 테스트를 진행.통합 테스트 : 외부의 영향까지 반영하여 테스트. 스프링부트 테스트, JPA 테스트 등 이렇게 분리해서 테스트를 진행하고자 하는 이유는 다음과 같습니다.테스트에 대한 빠른 피드백테스트 할 때 빠른 피드백과 빠른 수정이 필수라고 생각합니다. 단위 테스트의 경우 외부 영향 없이, mock을 통해 빠르게 내가 목록화한 테스트를 진행하며, CI 환경에서도 빠르게 피드백을 받을 수 있습니다.반면, 통합 테스트의 경우 비교적 시간 소비가 많이 됩니다. 스프링부트 테스트의 경우 비교적 적은 시간이 소비되지만, JPA 테스트와 같이 디비에 대한 테스트 혹은 다른 플랫폼( 예 : 키클락 등)을 진행하기 위해서는 테스트 컨테이너와 같은 도구를 활용할 수 있다고 생각합니다. 이러한 도구를 사용함에 있어서 많은 시간이 소비가 될 가능성이 크다고 생각합니다.특히 저희 회사의 경우 테스트 환경이 많이 좋지 않아 시간이 훨씬 더 많이 걸리게 됩니다.그래서 저는 단위 테스트랑 통합 테스트를 분리하여 개발 환경에서는 단위 테스트를, 운영 CI 환경에서는 단위 + 통합을 함께하여 테스트를 진행하고 있습니다. 이렇게 분리해서 진행하는 것은 나름 장점이 보이고 있다고 생각하는데 이 부분에 대해 강사님의 의견과 잘못된 부분이 있다면 피드백 부탁드립니다.
-
해결됨Spring Boot TDD - 입문부터 실전까지 정확하게
아키텍처 개선
안녕하세요.양질의 강의 덕분에 제한된 시야에서 새로운 인사이트를 얻을 수 있었습니다.섹션 18 - 안정감 있는 아키텍처 개선 챕터를 수강하고 있으며, 현재까지 강의를 들으면서 궁금 했던 내용 두 가지를 여쭈어보고 싶습니다. 질문 1."TDD를 사용해 만들어진 먹구름 아키텍처를 어느 시점에서 개선 해야 할까요?"질문을 하게 된 계기는 전형적으로 많이 사용되는 레이어드 아키텍처를 첫 기능 구현 단계에서 부터 차용하여 개발을 진행 해왔는데, 왜 이 아키텍처를 사용했을까? 란 의문이 없었거든요.강의에서는 흔히 말해 스마트 UI 패턴으로 요구사항을 충분히 충족 해오며 점진적으로 개선 해왔습니다.그러다 모종의 이유로 내부 아키텍처를 개선 하면서 진행이 되었는데, 아키텍처를 개선 해야겠다고 느끼는 요소가 무엇인지 궁금합니다.요구사항이 추가 되었을 때 개발 비용을 최소화 하여 충족 시킬 수 있는가? 라고 생각을 하고 있는데, 현재 까지 불편함을 느낄 정도의 확장성을 강요 받아본 적 없어서 감을 못 잡는 것 같습니다. 질문 2."어떤 영역을 대상으로 테스트를 작성해야할까?"- 테스트 코드 작성 범위 고민위 질문 내용과 답변을 보고 무언가 감이 오는 듯 하나, 아직 정리되지 않는 느낌입니다.API 계층의 동작이 가볍다 또는 무겁다의 판단 기준 API 계층의 동작이 가벼운지 무거운지에 대한 판단은 어떻게 하시는지 궁금합니다.해당 강의에선 API 계층의 동작이 가벼웠기 때문에 API 스펙에 인수테스트를 진행 한 것 같습니다. 서비스 대상으로 테스트를 많이 실행하고, API 는 간단한 성공 경우에 테스트를 한다. 이 케이스에선 아래와 같은 테스트 시나리오가 있다고 가정한다면 테스트를 어떻게 하면 좋을까요?- username 속성이 null 이거나 공백이라면 HasUsernameNullOrEmpty 예외를 반환한다 - username 속성이 올바른 형식을 따르지 않으면 InvalidUsername 예외를 반환한다 - username 속성이 올바른 형식을 따르면 User 객체를 생성한다서비스 테스트에서 위 3가지 케이스에 대해 검증인수 테스트에서 username 을 정확히 입력한 경우 상태코드와 유저에 대한 정보를 반환 하는지 검증 이렇게 테스트를 구성한다고 이해 했는데 제대로 이해한걸까요? 다시 한 번 질문을 빌미로 감사 인사를 드리면서 고견 부탁드리겠습니다.항상 건강하세요!
-
해결됨Spring Boot TDD - 입문부터 실전까지 정확하게
병렬 처리 시 질문
강사님 안녕하세요.전에 독립적인 환경에서 실행하면 병렬처리가 된다고 하셨던 것 같은데,그렇다면 생성하는 코드 후 id 비교를 할 때다른 테스트 코드에서 상품이 등록되어 반환되는 리스트가 달라질 수 있다고 생각됩니다.그렇다면 이런 경우에는 이 테스트가 진행될 때는 다른 테스트가 동작하지 않게 처리하던가 하는 방식이 있나요? 예를 들어 최신 리스트를 반환한다고 할 때테스트 리스트를 넣고 act 하기 전에 다른 테스트에서 arrange 단계에 추가 코드가 동작되면act에서 리스트 조회할 때 반환할 때 다른 곳에서 추가한 값이 반환되어 테스트 실패 이렇게 될 것 같아 질문드립니다.좋은 강의 감사드립니다.
-
해결됨Spring Boot TDD - 입문부터 실전까지 정확하게
assertThat 상태 코드 비교
학습 관련 질문을 남겨주세요. 구체적으로 적을수록 좋아요!마크다운과 단축키를 활용하면 글을 더 편하게 작성할 수 있어요.커뮤니티 질문 & 답변에 비슷한 내용이 있었는지 먼저 검색해보세요.서로 예의를 지키며 존중하는 분위기를 함께 만들어가요.잠깐! 인프런 서비스 관련 문의는 1:1 문의하기를 이용해 주세요안녕하세요 좋은 강의 만들어주셔서 감사합니다. 실무에 적용할 수 있도록 열심히 듣고 있습니다.강의 내용과는 조금 거리가 있는 질문일수도 있겠으나 궁금해져서 여쭤봅니다. assertThat으로 응답코드 검증 시 getStatusCode().value() 와 200으로 직접 코드값을 검증하시는 이유가 있을까요? getStatusCode() 와 HttpStatus.OK 로 enum 타입 검사가 의도가 명확하지 않나? 라는 의문이 들어서 특별한 이유가 있으신 건지 궁금해서 질문 남겨봅니다
-
해결됨Spring Boot TDD - 입문부터 실전까지 정확하게
테스트 격리에서 테스트 랜덤 실패 이유
69강 테스트 격리에서 테스트가 랜덤으로 실패하는 이유가 뭔가요?싱글톤때문에 발생하는 문제인건 알겠는데 조회할 때 Exception이 생기는 이유를 모르겠습니다. ㅠㅠ
-
미해결Spring Boot TDD - 입문부터 실전까지 정확하게
테스트 코드 작성 범위 고민
안녕하세요! TDD 평소에 관심이 많았지만 실무에서 막상 적용하려니 고민이 많았는데 좋은 강의 만들어 주셔서 감사합니다. 섹션5까지 수강했는데 벌써 만족스럽네요 수강평 5점 먼저 드렸고 평소에 실무에서 항상 고민이 되던 부분이 있어서 질문드려요! 테스트코드가 너무 많아지는 것이 부담스러워서 하는 고민인데요. 특정 Service 메서드의 테스트코드를 작성 할 때 해당 메서드가 사용하고 있는 Repository 메서드 에서 테스트한 내용을 Service 에서 중복적으로 테스트해야하는 가에 대한 고민입니다. 참고로 Service, Repository 메서드 둘다 응답에 영향을 미치는 동일한 파라미터를 인풋으로 받고 있다는 전제입니다. GPT 에게 물어보면 아래와 같이 대답을 하는데요. 서비스 메서드의 인풋값이 변경되면 응답에 영향을 미치는데 Repository에서 테스트했다고 안하는 것이 맞는가? 라는 고민이 계속 되네요. 고견 주시면 감사하겠습니다![GPT 답변]Service 테스트는 Repository 동작이 "올바르다고 믿는다는 전제 하에" 작성하는 것이 일반적인 전략입니다.즉, Repository의 구현 자체를 Service 테스트에서 다시 검증할 필요는 없습니다. 질문 카테고리가 "수업질문"인데 전체질문으로 변경하는 버튼이 없어서 일단 그대로 둡니다 ㅜㅜ
-
미해결Spring Boot TDD - 입문부터 실전까지 정확하게
질문드립니다.
안녕하세요! 강의 절반을 본 수강생입니다.뒷내용에 나올법한데 질문드려봅니다. 강의에서 거짓음성에 대한 경험때문에 테스트 코드에 @Transactional 를 안붙이신다고 하셨습니다. 그럼 예를 들어서 개발 디비기준으로 CRUD 테스트를 작성하시는건가요? 또 다른 질문으론TDD 기법이 아닌 , 실무 회사 코드에서 기존 코드에 인터페이스 테스트를 작성하려고 합니다 TDD가 아닌 유닛테스트로 이해가 되는데, 이런 방법또한 상관 없을까요?
-
미해결Spring Boot TDD - 입문부터 실전까지 정확하게
cqrs 명령 아키텍처 개선 질문
안녕하세요 선생님 제가 이해가 잘 안된걸 수 있어서 확인차 질문 드립니다!var executor = new RegisterProductCommandExecutor(productRepository::save); executor.execute(command, uuid, sellerId);명령 조회를 개선하면 RegisterProductCommandExecutor 라는 실행기를 만들어서 execute 로 실행하는 동작으로 이 구조를 pdf 자료에서 확인하면궁금한점이명령모델이 new RegisterProductCommandExecutor(productRepository::save); 로 실행기를 만들면 명령모델이 실행기를 만들면서 productRepository 라는 기반구조에 의존하고 있는거 아닌가요? 구조자체에서 보면 명령실행기는 execute 를 통해서 실행기가 참조하는 기반구조 기능을 실행하는 건 직접 의존하지 않아서 자유도가 높아보인다? 라는 생각이드는데요, 실행기를 만들때 명령모델은ProductRepository 를 알아야할 것같아서 의미가 없어보입니다.실행기를 만들때 실행기 자체가 bean으로 등록이 되고 실행기 bean 안에서 ProductRepository 를 스프링에서 주입받고, 실행기를 만드는 명령 모델은 실행기만 주입받고 파라미터로 repository 를 넘겨도 되지 않으니 이게 정말 의존하지않는 구조같은데요.(제가 말한 (2) 방식이라면) 이이렇게 되면 그냥 돌고돌아서 결국엔 처음 방식인 ProductRepository 인터페이스를 (추상화 되어있으니) 그냥 바로 빈을 주입받는 것이랑 별차이 없다고 생각합니다조회도 역시 이런생각이 들었습니다. 명령과 조회를 분리한다는 개념은 이해가 갈거같은데 각 명령과 조회 모델이 기반구조에 의존? 한다는 개념을 잘 이해가 가지 않습니다!
-
미해결Spring Boot TDD - 입문부터 실전까지 정확하게
거짓 양성 감지 노하우 질문입니다
안녕하세요 규원님. 강의 잘 듣고 있습니다. 제가 실습 코드를 따라하다가 오탈자가 생겨 이를 해결하는 과정에서 의문점이 생겨 질문 남깁니다. shopper 토큰 발급 엔드포인트 구현 과정에서 @RequestBody 어노테이션을 누락했습니다@PostMapping("/shopper/issueToken") ResponseEntity<?> issueToken(IssueShopperToken query) { return repository.findByEmail(query.email()) .map(shopper -> composeToken()) .map(AccessTokenCarrier::new) .map(ResponseEntity::ok) .orElseGet(() -> ResponseEntity.badRequest().build()); }문제는 이런 상황에서 400이 발생하며 실패해야할 테스트 코드가 통과하게 됩니다.@Test void 잘못된_비밀번호가_사용되면_400_Bad_Request_상태코드를_반환한다( @Autowired TestRestTemplate client ){ // Arrange var email = generateEmail(); var wrongPassword = generatePassword(); var password = generatePassword(); client.postForEntity( "/shopper/signUp", new CreateShopperCommand(email, generateUsername(), password), Void.class ); // Act ResponseEntity<AccessTokenCarrier> response = client.postForEntity( "/shopper/issueToken", new IssueShopperToken(email, wrongPassword), AccessTokenCarrier.class ); // Assert assertThat(response.getStatusCode().value()).isEqualTo(400); }이유를 고민해보고 다음과같은 결론을 짓게 되었습니다.@RequestBody가 없는 경우 컨트롤러 메서드의 매개변수는 기본적으로 form data로 인식하게 된다.따라서 IssueShopperToken이 form data로 인식되게 된다.현재 테스트에서는 상태코드가 400인지만을 확인한다.하지만 form data가 없는 경우에도 400이 발생한다.테스트가 통과한다. 거짓 양성의 사례라고 보여집니다. 이경우에는 Assert절을 강화해 상태코드 말고도 검증되어야할 항목들을 추가해 거짓 양성을 방지할 수 있을거라고 생각됩니다. 이렇듯 테스트코드도 사람이 작성하다 보니 Assert절을 어느정도 수준까지 구체적으로 작성해야 할지를 TDD가 익숙하지 않다면 빠르게 식별하기 어렵다고 생각합니다.실무에서는 이와같은 상황은 매우 치명적일 수 있을거 같고요.그래서 실무에서 필요한 Assert절을 구체화하는 명확한 기준이나 노하우가 있으신지가 궁금합니다!
-
미해결Spring Boot TDD - 입문부터 실전까지 정확하게
질문드립니다.
안녕하세요 TDD에 관심 있는 개발자입니다.좋은 강의 만들어주셔서 감사합니다. 강의에 대한 질문이 아닌 실무적인 질문드립니다.뒷 내용을 못봐서,, 지금까지 보면서 궁금했던 내용 질문드립니다. 상황마다 다르겠지만 형상관리하는 시점이 언제정도 될까요? 제 생각엔 Green 상태에 커밋을 할텐데 Green 상태는 단순히 api 상태값만 통과하는 기준일까요..?디비 먼저 설계가 아닌 인터페이스설계 테스트를 하고 필요시 디비 스키마를 작성한다라고 이해 하였습니다만 결국 해당 테스트 시나리오를 전부 만족 한다면, API 개발이 끝난 상태라고 할수 있는 건가요?리팩토링은 선택이라고 강의에서 이야기 해주셨는데 예를 들어서 @Valid 라는 애노테이션으로 외부 인터페이스의 값을 필터링 해서 상태값을 반환해주겠다라는 내용일까요?실무적으로 테스트 시나리오는 노션에 작성하신다고 하셨는데 이슈 트래킹 ( 지라 등등) 쪽을 작성하시는게 더 좋을까요?
-
해결됨Spring Boot TDD - 입문부터 실전까지 정확하게
프로젝트 규모가 큰 경우 @SpringBootTest 실행 속도 문제
안녕하세요, 강사님.저는 백엔드 1년 차 주니어 개발자입니다. 강사님 덕분에 TDD 학습을 차근차근 진행하고 있는데, 한 가지 궁금증이 생겨 질문드립니다. 현재 강의에서는 매번 API 기능을 구현할 때마다 @SpringBootTest 를 사용하여 테스트하고 계신데요. 만약 프로젝트 규모가 엄청 커져서 컨텍스트 로딩 시간이 5초 이상이 소요되는 경우,테스트 결과를 기다리느라 “개발 흐름이 끊기는” 문제가 발생할 것 같은데요. 현업에서는 이 부분을 어떻게 관리하시는지 궁금합니다. 매번 @SpringBootTest를 그대로 사용하며 시간을 감수하시는지특정 테스트만 빠르게 실행하는 슬라이스 테스트(@WebMvcTest 등)를 병행하시는지그 외 다른 최적화 기법이 있는지 조언 부탁드립니다. 😊
-
미해결더 자바, 애플리케이션을 테스트하는 다양한 방법
테스트 반복하기 관련 질문입니다
@DisplayName("파라미터 테스트") @ParameterizedTest(name = "{index} {displayName} message={0}") @ValueSource(ints = {10, 20, 40}) void parameterizedTest(Study study){ System.out.println(study.getLimit()); }Junit5 테스트 반복하기 2부에서 이 부분 질문드리려 합니다. 강의에서는 Study 타입으로 받아서 객체를 생성하고 getLimit으로 값 가져오는 것까지 묵시적으로 진행이 잘 되었습니다만, 제 환경에서는 ```javaError converting parameter at index 0: No built-in converter for source type java.lang.Integer and target type com.example.testpractice.Studyorg.junit.jupiter.api.extension.ParameterResolutionException: Error converting parameter at index 0: No built-in converter for source type java.lang.Integer and target type com.example.testpractice.Study at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183) at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179) at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183) at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183) at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)``` 와 같은 에러가 발생해서 Junit이나 JDK의 버전에 따라 스펙이 바뀌었는지 궁금해져서 질문드립니다
-
미해결스프링부트 JUnit 테스트 - 시큐리티를 활용한 Bank 애플리케이션
요청/응답 DTO 관련 문의
안녕하세요, dto 관련 문의드립니다. 요청/응답 DTO를 왜 static으로 만드나요?이전 데이터가 유지되지 않나요?? 매번 객체를 만들면 안되나요? @Getter @Setter public static class AccountWithdrawReqDto { @NotNull @Digits(integer = 4, fraction = 4) private Long number; @NotNull @Digits(integer = 4, fraction = 4) private Long password; @NotNull private Long amount; @NotEmpty @Pattern(regexp = "^(WITHDRAW)$") private String transactionType; }//ATM -> 계좌 @Transactional public AccountWithdrawRespDto 계좌출금(AccountWithdrawReqDto accountWithdrawReqDto, Long userId) { //1. 0원 체크 if (accountWithdrawReqDto.getAmount() <= 0L) throw new CustomApiException("0원 이하의 금액을 출금할 수 없습니다."); //2. 출금 계좌 확인 Account withdrawAccountPS = accountRepository.findByNumber(accountWithdrawReqDto.getNumber()) .orElseThrow(() -> new CustomApiException("계좌를 찾을 수 없습니다.")); //3. 본인 확인 withdrawAccountPS.checkOwner(userId); //4. 패스워드 확인 withdrawAccountPS.checkPassword(accountWithdrawReqDto.getPassword()); //5. 출금계좌 잔액 확인 // withdrawAccountPS.checkBalance(accountWithdrawReqDto.getAmount()); //6. 출금 (잔액 확인이 누락되면 안되므로 출금 메소드에 녹인다!) withdrawAccountPS.withdraw(accountWithdrawReqDto.getAmount()); //7. 거래 내역 Transaction transaction = Transaction.builder() .withdrawAccount(withdrawAccountPS) .depositAccount(null) .withdrawAccountBalance(withdrawAccountPS.getBalance()) .depositAccountBalance(null) .amount(accountWithdrawReqDto.getAmount()) .sender(withdrawAccountPS.getNumber().toString()) .receiver("ATM") .transactionType(TransactionEnum.WITHDRAW) .build(); Transaction transactionPS = transactionRepository.save(transaction); return new AccountWithdrawRespDto(withdrawAccountPS, transactionPS); }
-
미해결쥬쥬와 함께 하루만에 끝내는 스프링 테스트
S3통합 테스트 질문
통합 테스트 돌리는 중에java.lang.RuntimeException: java.net.URISyntaxException: Expected scheme-specific part at index 10: localhost:이런 에러가 나서 헤매고 있습니다 ㅜㅜ노션이랑 강의 다시 돌려보면서 틀린 부분 찾고 있는데 없는 것 같고요 scheme문제라고 해서 properties파일을aws.endpoint=localhost:4566 이거 에서aws.endpoint=http://localhost:4566 요걸로 바꿔도 에러가 발생하네요 어떻게 해결해야하나요?
-
미해결쥬쥬와 함께 하루만에 끝내는 스프링 테스트
성적 저장 어플 만들기 강의 관련 질문
강의 17분쯤에 save메서드를 postman에서 테스트를 해보았는데 Internal Server Error가 떠서 확인해보니cannot deserialize from Object value (no delegate- or property-based Creator) 에러가 뜨는 것을 확인할 수 있었습니다. 그래서 기존에@Getter @AllArgsConstructor public class SaveExamScoreRequest { private final String studentName; private final Integer korScore; private final Integer englishScore; private final Integer mathScore; }이렇게 써져있는 코드를@Getter @AllArgsConstructor @NoArgsConstructor public class SaveExamScoreRequest { private String studentName; private Integer korScore; private Integer englishScore; private Integer mathScore; }이렇게 바꾸니 정상적으로 응답을 반환함을 확인할 수 있었습니다.알아보니 해당 에러는 jackson생성자가 빈 생성자가 없는 객체를 만드는 법을 모르기 때문에 뱉는 에러라고 설명되어있어서 @NoArgsConstructor어노테이션을 추가하였고 final을 지워주었습니다.근데 강사님의 코드는 잘 돌아가는데 왜 제 코드는 저런 에러가 발생하는지 모르겠습니다. 혹시 스프링 버전하고도 관련이 있나요? (저는 현재 spring boot 3.4.1 버전을 사용하고 있기는 합니다.)
-
미해결더 자바, 애플리케이션을 테스트하는 다양한 방법
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" 만을 사용해서 테스트 컨테이너를 구동시켜 테스트해도 되는지 여쭤보고 싶습니다. 예를 들어 이런 식으로 입니다. 질문 읽어주셔서 감사합니다.