묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결나도! 스프링으로 인공지능을 할 수 있다(인프1탄)
실제로 LLM으로 전달된 질문을 볼 수 있는 방법을 알 수 있을까요 ?
안녕하세요 강의 잘 듣고 있습니다.제목 그대로 실제로 LLM으로 전달된 질문을 볼 수 있는 방법을 알 수 있을까요 ? ListOutputConverter 클래스 내부를 보면 getFormat() 이라는 메서드가 있는데 왠지 LLM 에 전달될 때 제가 입력한 메시지에 추가적인 메시지가 포함되어서 LLM 으로 전달되는것 같은 느낌입니다. 실제 LLM 으로 전달되는 메시지 정보를 볼 수 있는 방법을 알고 싶습니다.
-
미해결실전! 스프링 데이터 JPA
왜 select에서 left join을 수행하더라도 count에서는 left join을 수행하지 않나요?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]안녕하세요, 강의 잘 듣고 있습니다. 질문도 드리고, 맞다면 메뉴얼에 추가할 만한 내용이 있는 것 같아서 글 남겼습니다! Page를 조회해올 때, left join을 사용한 경우, countQuery에 대해 명시하지 않더라도 count 쿼리문에서는 join 문이 확인되지 않았는데, 이것 또한 하이버네이트6에서 최적화하여 join 문을 생략한 것일까요? 하이버네이트6에서 left join을 직접 추가하더라도 내부적으로 최적화하는 질문을 보고 메뉴얼("스프링 부트 3 - 하이버네이트 6 left join 최적화 설명 추가")도 확인했습니다.그럼에도 join을 강제로 수행시켜도 count 쿼리 또한 join 돼서 수행되는지 확인하고 싶어 다음과 같이 코드를 작성해봤습니다.@Query(value = "select m,t from Member m left join m.team t") Page<Member> findPageByAge(int age, Pageable pageable);@Test public void paging() { //given memberRepository.save(new Member("member1", 10)); memberRepository.save(new Member("member2", 10)); memberRepository.save(new Member("member3", 10)); memberRepository.save(new Member("member4", 10)); memberRepository.save(new Member("member5", 10)); int age = 10; PageRequest pageRequest = PageRequest.of(0, 3, Sort.by(Direction.DESC, "username")); Page<Member> page = memberRepository.findPageByAge(age, pageRequest); //then List<Member> members = page.getContent(); long totalElements = page.getTotalElements(); assertThat(members.size()).isEqualTo(3); assertThat(totalElements).isEqualTo(5); assertThat(page.getNumber()).isEqualTo(0); assertThat(page.getTotalPages()).isEqualTo(2); assertThat(page.isFirst()).isTrue(); assertThat(page.hasNext()).isTrue(); }테스트 코드는 강의와 똑같이 작성하고, 쿼리문에서 select m, t로 한 뒤 countQuery는 별도로 추가하지 않았습니다.이때, 수행되는 쿼리가 다음과 같은데,select m1_0.member_id, m1_0.age, m1_0.team_id, m1_0.username, t1_0.team_id, t1_0.name from member m1_0 left join team t1_0 on t1_0.team_id=m1_0.team_id order by m1_0.username desc fetch first ? rows onlyselect count(m1_0.member_id) from member m1_0countQuery를 명시하지 않았음에도, 강의와 달리 count 쿼리문에서는 join이 수행되지 않았습니다.
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
안녕하세요 ExceptionHandler 관련하여 질문 있습니다.
만약에 ExceptionHandler를 사용하지 않고 글로벌 예외를 처리해야 한다면 필터에서 처리하는게 좋을지 인터셉터에서 처리하는게 좋을지 궁금합니다.
-
해결됨실전! 스프링 데이터 JPA
하이버네이트 프록시객체 질문
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]안녕하세요 영한 님 강의를 들으며 공부하던 중 findAll 메서드를 통해 가져온 List<Member> members의 각 Member들이 team 필드에 프록시 객체를 들고 있다고 말씀하셨는데, 해당 프록시 객체의 값을 디버깅해 본 결과 그 안에 이미 값이 존재 했습니다. console을 확인해보니 아직 db에 쿼리를 날리기 전인데(쿼리를 날리기 전인지 p6spy에 들어오기 전인지는 확인하지 못한 점 죄송합니다.) members의 각 Member들의 team필드에 프록시 객체가 존재하지만 그 안에 이미 team의 값이 들어있는데 em.clear()를 통해 영속성콘텍스트마저 비워줬는데 어떻게 이미 알고 있는 건가요?
-
미해결스프링 핵심 원리 - 기본편
"스프링이란"이라는 강의까지 듣고 질문 올려봅니다~
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. 스프링부트의 장점으로"단독으로 실행할 수 있는 스프링 애플리케이션을 쉽게 생성"이라는 말이 나오면서 톰캣같은 웹서버를 내장하고 있다고 해주셨는데,톰캣은 그러면 스프링부트에 내장된 “웹서버”이기도 하면서 “WAS”이기도 한 것일까요?아니면 톰캣은 "웹서버"만을 지칭하는 건가요?
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
editForm의 형태가 이상하게 나옵니다!
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. 강의를 들으면서 하고있는데 상품 등록은 문제 없이 되는데상품 등록한 이후에 상품 수정을 하려고 들어가면 ui가 좀 깨지는 모습이 있습니다.위의 사진처럼 가격의 크기가 너무 압도적으로 큽니다. 일단 영한님의 코드를 그대로 복사 붙히기를 해도 같은 결과가 나옵니다. 그래도 저의 editForm 코드도 같이 첨부합니다.<!DOCTYPE HTML> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="utf-8"> <link href="../css/bootstrap.min.css" th:href="@{/css/bootstrap.min.css}" rel="stylesheet"> <style> .container { max-width: 560px; } </style> </head> <body> <div class="container"> <div class="py-5 text-center"> <h2>상품 수정 폼</h2> </div> <form action="item.html" th:action method="post"> <div> <label for="id">상품 ID</label> <input type="text" id="id" name="id" class="form-control" value="1" th:value="${item.id}" readonly> </div> <div> <label for="itemName">상품명</label> <input type="text" id="itemName" name="itemName" class="formcontrol" value="상품A" th:value="${item.itemName}"> </div> <div> <label for="price">가격</label> <input type="text" id="price" name="price" class="form-control" th:value="${item.price}"> </div> <div> <label for="quantity">수량</label> <input type="text" id="quantity" name="quantity" class="formcontrol" th:value="${item.quantity}"> </div> <hr class="my-4"> <div class="row"> <div class="col"> <button class="w-100 btn btn-primary btn-lg" type="submit">저장</button> </div> <div class="col"> <button class="w-100 btn btn-secondary btn-lg" onclick="location.href='item.html'" th:onclick="|location.href='@{/basic/items/{itemId}(itemId=${item.id})}'|" type="button">취소</button> </div> </div> </form> </div> <!-- /container --> </body> </html>
-
미해결재고시스템으로 알아보는 동시성이슈 해결방법
NamedLock 테스트 실패
안녕하세요 상용님 좋은 강의 너무 잘 듣고 있습니다.namedlock부분에서 테스트 코드를 돌리는데 connectiontimeout 이후 테스트가 실패하여 질문 드리려 합니다.문제상황maximum-pool-size를 40으로 설정 후 테스트를 돌리면 다음과 같은 에러가 터지면서 테스트가 실패합니다. 사진에서와 같이 40개 스레드가 락획득을 시도한 후, 30초 후 락획득 시도조차 하지못한 60개의 스레드에서 타임아웃이 납니다.이후 락 획득을 기다리던 스레드하나가 타임아웃이 나고 나머지 스레드들이 39번의 재고 감소 로직을 실행합니다.추측제가 추측한 것은 다음과 같습니다.1. 현재 transactional propagation requiresnew로 되어있기에 하나의 재고 감소 로직 당 2개의 connection을 필요로한다.2. 처음 40개의 스레드가 순차적으로 lock획득을 시도하며 40개의 스레드를 점유한다.3. requires new로 새로운 트랜잭션을 시작하기 위해 새 connection이 필요하지만, 여유분이 없어 기다린다.(이때 데드락 상황)4. 30초 대기후 timeout이 나서 커넥션들이 순차적으로 반환된다.5. 이때 락을 획득 시도한 스레드(커넥션 점유중)가 반환되면6. 나머지 39개의 락획득 시도하던 스레드들이 실행된다.그래서 실제로 maximum pool size를 101개로 올리니 잘 실행되었습니다.그런데 선생님은 40개로도 실행이 되어서.. 의문이 남습니다.질문저의 추측이 맞을까요..? 틀리다면 어디가 틀린걸까요.왜 선생님은 40으로만으로도 된것인가요?이런 이유에서 강의 중에 datasource를 분리하라 하신걸까요?혹시 몰라 코드 첨부합니다.!
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
localhost/hello 404에러
View 환경설정 부분에서localhost:8080/hello 부분이 접속이 안됩니다.작성코드 결과화면
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
findByname파트에서 질문이 있습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.회원 리포지토리 테스트 케이스 작성 8:48영상을 보았는데Member result = repository.findByName("spring1").get(); 이렇게 코드를 치는걸로 나오는데 이런방식으로 하면 값이 있는지 여부를 파악 못하고 그냥 불안전하게 값을 가져오는 방식이라는걸로 예전에 다른 강의에서 말씀해주셨던 거 같은데 기억이 애매모호해서 질문드립니다. 테스트코드라서 이런방식을 택하신건지와 정석적으로 값을 체크하려면 아래방식으로 코드를 짜는지에 대해서 궁금합니다.Optional<Member> result = repository.findByName("spring1"); Assertions.assertThat(result) .isPresent() // Optional에 값이 있는지 확인 .get() // 값이 존재할 때만 안전하게 꺼냄 .isEqualTo(member1);혹시 이 코드가 맞다면 Optional<Member> 대신에 Member 클래스를 넣으면 정석인 코드가 되는지 알고 싶습니다.
-
미해결스프링 부트 - 핵심 원리와 활용
Config 클래스에 @AutoConfiguration 의 필요성
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]안녕하세요 org.springframework.boot.autoconfigure.AutoConfiguration.imports에 설정 클래스를 등록하면 importSelector가 해당 클래스를 읽어온 후 설정 클래스 및 내부 빈들이 등록되는 것으로 이해했습니다. 그런데 설정 클래스에서 @AutoCongiruation 이라는 어노테이션을 붙여주는 이유가 뭔지 잘 모르겠습니다. 해당 어노테이션을 제외하고 public class MemoryAutoConfig { @Bean public MemoryController memoryController() { return new MemoryController(memoryFinder()); } @Bean public MemoryFinder memoryFinder() { return new MemoryFinder(); } } 이런형태로 build한뒤 다른 프로젝트에서 implementation 을했을 때도 MemoryController와 MemoryFinder가 빈으로 등록되고 동작하는 것을 확인했습니다. imports파일에 등록하는 클래스는 자동으로 빈으로 읽혀지는 것 같은데, 해당 클래스에 @AutoConfiguration 을 붙여주는 이유가 궁금합니다
-
해결됨서버개발자 과제전형 완벽가이드 - 1편
SPOCK 의존성 추가 후 Generate Test 옵션 미노출
안녕하세요 강사님spock의 의존성 추가 후(build완료) generate test 창에서 target library에 spock이 뜨지 않습니다. 혹시 강사님이 추가로 설치하신 plugin이나 세팅이 있을까요?
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
DTO 분리
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]안녕하세요 좋은 강의 항상 감사드립니다. 강의를 수강 하던 중 간단한 질문이 있어 작성하였습니다! OSIV를 끄기 위해 분리를 하실 때 QueryService를 만드시면서 동시에 기존의 DTO들을 사용하지 않으시고 Query 패키지에 새로 만들어 사용하셨는데 기존 DTO를 사용하지 않는 이유가 궁금합니다!또한 이렇게 분리해서 새로 만드는 것이 권장되는 사항인지 궁금합니다!
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
Valid체크 오류 문의드려요
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]상품등록시에서도 입력받는 책 데이터들의 valid를 체크하고싶어서 memberForm을 받을때와 마찬가지로코드를 짰는데 계속해서 오류가 납니다... 아무리 찾아봐도 모르겠어서 질문 남깁니다(name만 null체크를 합니다.) BookFormItemController templates/items/createItemForm.html오류
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
web,was 분리 관련
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]로드맵을 다 돌고 이 강의를 다시 듣고있는데 웹 시스템 구성은 web, was, db로 하는것이 좋다는 말이 귀에 들어왔습니다.강의를 따라하면서 프로젝트를 따라할 때 spring boot 안에 내장되어있는 tomcat을 쓰고있는 것으로 아는데 저희는 따로 web과 was를 따로 분리해서 작업하고 있는게 아닌가요? 만약 따로 분리를 한다면 어떻게 하는것이 따로 하는것이라고 생각할 수 있을까요?
-
미해결스프링 시큐리티 완전 정복 [6.x 개정판]
SecurityContextHolder 는 DTO 같은 개념일까요?
강의를 다시 복습하니, SecurityContextHolder 가 지연로딩을 해 주는 역할도 하지만 다른 필터에 SecurityContext를 전달하는 DTO 같은 역할을 하는 것 같다고 느꼈는데 선생님 생각은 어떠신가요?
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
sql-error-codes.xml에 없는 DB 종류를 사용할 경우
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]해당 파일을 커스터마이징 해야 하나요 ? 예를 들어 티베로 + 스프링 조합으로 개발을 하게 되면 예외 처리를 개발자가 직접 해줘야 한다고 생각하면 될까요 ?
-
미해결실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
테스트 후 AfterEach 함수에서 나오는 쿼리
안녕하세요 fetch join까지 적용한 후에 테스트 코드 자체가 N+1 문제가 제거된 것은 확인했습니다.그런데 AfterEach 함수에서 deleteAll을 하는 과정에 fetch join 이전의 N+1 쿼리랑 유사한 쿼리가 나오는데 이게 delete 쿼리를 날리기 위한 데이터를 가져오려는 목적인것 같은데 질문이 있습니다. 혹시 deleteAll 이전에 나오는 쿼리도 N+1처럼 동작하는지테스트 코드이므로 테스트 객체의 모수가 작아 무시해도 되는지이정도 질문하고 싶습니다
-
미해결스프링 시큐리티 완전 정복 [6.x 개정판]
9분 50초경 default 접근제어자의 이유
선생님 , 안녕하세요. 강의 잘듣고 있습니다!질문이 있어서 글남기게 됩니다! 이번 강의 9분 50초 정도에 AuthoriationManger 인터페이스는 접근제어자가 public으로 되어있는데, 하위 메서드인 verify는 접근제어자가 default로 되어있습니다! 위의 이유가 궁금합니다. AuthrozationManager 와 같은 패키지내의 클래스에서만 verify 메서드에 접근 가능하도록 제한을 두기 위한 것인지 아니면 다른 이유가 있는지 궁금합니다.답변 부탁드리겠습니다! 항상 좋은 강의 감사드립니다.
-
해결됨Practical Testing: 실용적인 테스트 가이드
Mockito로 Stubbing하기 8분경 OrderRepository 테스트
학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요!먼저 유사한 질문이 있었는지 검색해 보세요.서로 예의를 지키며 존중하는 문화를 만들어가요. 안녕하세요 강의를 보다가 OrderRepository에 대한 테스트는 직접 짜보라는 말씀을 듣고 직접 한번 작성을 해봤습니다. @ActiveProfiles("test") @DataJpaTest class OrderRepositoryTest { @Autowired private OrderRepository orderRepository; @Autowired private ProductRepository productRepository; @DisplayName("원하는 주문 상태를 가진 주문들을 조회한다.") @Test void findOrdersBy() { // given Product product1 = createProduct("001", HANDMADE, SELLING, "아메리카노", 4000); Product product2 = createProduct("002", HANDMADE, HOLD, "카페라떼", 4500); Product product3 = createProduct("003", HANDMADE, STOP_SELLING, "팥빙수", 7000); productRepository.saveAll(List.of(product1, product2, product3)); Order order1 = createOrderWithOrderStatus(List.of(product1, product2), LocalDateTime.now(), PAYMENT_COMPLETED); Order order2 = createOrderWithOrderStatus(List.of(product3), LocalDateTime.now().minusDays(1), PAYMENT_COMPLETED); Order order3 = createOrderWithOrderStatus(List.of(product1, product2, product3), LocalDateTime.now().plusDays(1), PAYMENT_COMPLETED); orderRepository.saveAll(List.of(order1, order2, order3)); // when List<Order> orders = orderRepository.findOrdersBy( LocalDateTime.now().minusDays(1), LocalDateTime.now().plusDays(1), PAYMENT_COMPLETED ); // then assertThat(orders).hasSize(2) .extracting("orderStatus", "totalPrice", "registeredDateTime") .containsExactlyInAnyOrder( tuple(PAYMENT_COMPLETED, 8500, order1.getRegisteredDateTime()), tuple(PAYMENT_COMPLETED, 15500, order3.getRegisteredDateTime()) ); } private Order createOrder(List<Product> products, LocalDateTime registeredDateTime) { return Order.create(products, registeredDateTime); } private Order createOrderWithOrderStatus(List<Product> products, LocalDateTime registeredDateTime, OrderStatus status) { Order order = createOrder(products, registeredDateTime); order.updateOrderStatus(status); return order; } private Product createProduct(String productNumber, ProductType productType, ProductSellingStatus sellingStatus, String name, int price) { return Product.builder() .productNumber(productNumber) .type(productType) .sellingStatus(sellingStatus) .name(name) .price(price) .build(); } }이런 식으로 작성을 하였는데 제가 궁금한 점은createProduct는 대부분의 테스트 클래스에서 사용되는데 하나의 static 클래스와 같이 외부로 분리하는게 좋지 않을까 라는 생각을 해봤습니다. 저는 Order 클래스의 상태 변경을 위해서 updateOrderStatus라는 메소드를 생성 하였는데 (아직 해당 강의를 끝까지는 보지 않고 강의를 보기전에 먼저 테스트 코드를 작성 해보고 있습니다) 이런 식으로 테스트를 위해서 메소드를 생성 하는 경우도 괜찮을까요?제가 작성한 코드의 given 절이 너무 길어지는 느낌을 받았습니다. 현재는 order와 product를 생성 하는 정도이지만 더 복잡한 로직을 생성 할 경우 given이 너무 길어 지는것에 대한 해결 방안이 있을까요? 최대한 구글을 사용하여 찾아는 보았지만 우빈님의 생각도 궁금하여 여쭤보았습니다! 긴 글 읽어주셔서 감사합니다 🙂
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
v1에서 POST할때 insert문 오류
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]여기에 질문 내용을 남겨주세요.Postman에서 http://localhost:8080/api/v1/members를 POST하는 것을 하고 있는데실행하면 아래와 같이 뜨고 insert into member (city, street, zipcode, name, member_id) values(NULL, NULL, NULL, 'hello', 1) 도 안뜨고 insert문 또한 한줄로 안나타나고 여러줄로 나옵니다...왜 이런걸까요 ?