묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결Practical Testing: 실용적인 테스트 가이드
createOrder 변경
학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요!먼저 유사한 질문이 있었는지 검색해 보세요.서로 예의를 지키며 존중하는 문화를 만들어가요. 안녕하세요 강의를 듣다가 의문점이 생겨 질문드립니다.createOrder의 test를 구현하기 위해 LocalTime을 인자로 받게 변경했는데 결국 test를 위해 비지니스 로직을 수정을 하는 과정이 너무 짜치는데 다른 방법은 없을까요? 강의 뒤쪽에 나오는 걸까요?
-
해결됨Practical Testing: 실용적인 테스트 가이드
"테스트 케이스 세분화하기" 강의 화면이 안나옵니다
다른 강의는 잘 나오는데 테스트 케이스 세분화하기 강의만 화면이 까맣게 나옵니다. 저만 그럴까요?Arc 브라우저에서 수강하다가 크롬 브라우저에서도 확인해봤는데 똑같이 화면이 안나옵니다. UPDATE 1: "테스트 케이스 세분화하기" 부터 화면이 안나오는 것 같네요.UPDATE 2: 크롬에서 하드웨어 가속 기능을 끄니까 정상적으로 화면이 나옵니다. 왜 기능을 꺼야하는건지 이유를 알고 싶긴하네요.
-
미해결Practical Testing: 실용적인 테스트 가이드
컨트롤러 테스트 시 POST시 Mockito.when() 처리에서 질문드립니다.
안녕하세요 제가 좀 더 응용해서 post 요청 시에 Mockito.when()과 접목시킨 테스트를 진행해봣는데 이 과정에서 질문이 있어 질문 드립니다. 예시 코드는 다음과 같습니다.void signUpTest() throws Exception { //given var memberResponse = new MemberResponse(MEMBER_ID, MEMBER_EMAIL); var signUpRequest = new SignUpRequest(MEMBER_EMAIL, "password"); //when when(memberFacadeService.signUp(signUpRequest)) .thenReturn(memberResponse); //then mockMvc.perform( post("/api/v1/members/signUp") .content(OBJECT_MAPPER.writeValueAsString(signUpRequest)) .contentType(MediaType.APPLICATION_JSON) ) .andDo(print()) .andExpect(status().isOk()) .andExpect(jsonPath("$.id").value(MEMBER_ID)) .andExpect(jsonPath("$.email").value(MEMBER_EMAIL)); }이 코드 시에 문제가 발생합니다. 문제는 java.lang.AssertionError: No value at JSON path "$.id"이거입니다. 근데, 이 코드를 아래와 같이 바꾸면 에러가 발생하지 않습니다.void signUpTest() throws Exception { //given var memberResponse = new MemberResponse(MEMBER_ID, MEMBER_EMAIL); var signUpRequest = new SignUpRequest(MEMBER_EMAIL, "password"); //when when(memberFacadeService.signUp(any(SignUpRequest.class))) .thenReturn(memberResponse); //then mockMvc.perform( post("/api/v1/members/signUp") .content(objectMapper.writeValueAsString(signUpRequest)) .contentType(MediaType.APPLICATION_JSON) ) .andDo(print()) .andExpect(status().isOk()) .andExpect(jsonPath("$.id").value(MEMBER_ID)) .andExpect(jsonPath("$.email").value(MEMBER_EMAIL)); }위와 아래의 차이는 requestBody에 들어가는 SignUpRequest 클래스를 mockBean처리 된 memberFacadeService의 when 처리 시에 해당 클래스를 any()로 처리하나 안처리하나의 차이입니다. 제가 예상하기에는 mockMvc에서 .content(objectMapper.writeValueAsString(signUpRequest)) 로 이렇게 처리했기 때문에 해당 로직에 들어가는 memberFacadeService 클래스의 signUp 매개변수로 들어가는 SignUpRequest가 제가 위에서 선언한 signUpRequest와 다르기 때문에 발생하는 문제라고 생각합니다. 이 이해가 맞는지에 대한 질문과 post요청에서는 다 이렇게 any()처리를 해야되는지 궁금합니다.
-
미해결더 자바, 애플리케이션을 테스트하는 다양한 방법
질문있습니다.
현재 스프링부트는 3.x버전대인데..버전대 맞춰서 예제나 소스코드를 변경해야할까요?..강의버전대는 2.1? 버전으로 알고있습니다..(지원하지 않은 코드가 있을경우)아울러 9월 이후로 답변주시지 않으신것같은데..질문이나 답변은 더 이상 안하시는것일까요?
-
해결됨Practical Testing: 실용적인 테스트 가이드
jpaRepository 에서 update 메서드 테스트 질문 드립니다.
jpaRepository에서 update 관련 메서드를 테스트하던 중 고민이 생겼습니다.update로 변경한 결과가 DB가 아닌, 영속성 컨텍스트에만 반영이 되어서 수정된 값을 확인하기 위해 find()메서드로 저장된 객체를 불러오면 수정한 것과 다른 원본 결과가 출력됩니다.이 문제를 해결하기 위해 두 가지 방법을 생각해보았습니다.하나는 @Modifying 애노테이션에 clearAutomatically = true 라는 옵션을 달아주는 방법이었는데, 이 방식은 테스트를 위해 프로덕션 코드를 수정하기도 하고 성능에 문제가 발생해서 제외하였고다른 하나는 테스트 코드에 EntityManager를 이용해 강제로 flush()와 clear()를 이용해 영속성 컨텍스트를 비워주도록 하는 방법이었습니다. 이 방식도 테스트 코드가 깔끔하지 않고 더 jpa에 종속적이게 되는 것 같아서 마음에 들진 않는데 강사님은 어떤 방식으로 해결하셨는지 궁금합니다!
-
미해결Practical Testing: 실용적인 테스트 가이드
a 서비스에서 b 서비스를 의존하는 코드에 대한 테스트는 어떻게 해야 되나요??
안녕하세요 강사님, 궁금한게있습니다.인스타그램, 페이스북을 사용할 때 제가 쓴 게시글에 다른 사람이 댓글을 달면 알림이 생성되는데, 제가 작성한 로직에서는 CommentService에서 댓글을 작성하고 alarmService를 호출하여 알림까지 생성하는 로직입니다.이렇게 로직을 짰을 때 제가 생각한 문제점에 대한 해답을 찾고 싶습니다.1. CommentService에서 다른 Service를 의존하게 되는 것2. 댓글 작성이라는 테스트를 짤 때 댓글 작성에 초첨을 맞출 수 없고 알림까지 테스트를 작성해야 되기 떄문에 핵심 기능 외에 다른 부가적인 기능 때문에 테스트의 집중도가 떨어집니다.3. 한 트랙잭션에 묶여서 알림을 생성하는데 문제가 발생하면 댓글도 생성되지 않습니다.이러한 경우 어떤 학습을 통해 개선할 수 있는지 가르쳐주실 수 있나요?
-
미해결Practical Testing: 실용적인 테스트 가이드
Mock과 Stub의 차이가 아직 잘 구분되지 않습니다.
개인적으로 Mock은 상태를 (내가 작성한 값을) 반환하는 것, Stub은 상태가 (내가 작성한 구현대로) 반환되는 것이라고 정의를 내리고 있습니다. 이와 같은 표현으로 차이를 이해하고 있어도 괜찮을까요?아니면 좀 더 명확한 표현이 있을까요? Mock 객체에 우리가 원하는 행위를 정의(Stubbing)하면,그 객체는 이제 Mock 객체라고 해야하나요 아니면 Stub 객체라고 해야하나요? 아래 코드를 보고 Mock 객체인 mailSendClient의 send 메서드에 대한 Stubbing이 이루어졌다. 라고 하면 맞는 표현인가요?@ExtendWith(MockitoExtension.class) class MailServiceTest { @Mock private MailSendClient mailSendClient; @Mock private MailSendHistoryRepository mailSendHistoryRepository; @InjectMocks private MailService mailService; @DisplayName("메일 전송 테스트") @Test void sendMail() { // given when(mailSendClient.send(anyString(), anyString(), anyString(), anyString())) .thenReturn(true); // when boolean result = mailService.sendMail("", "", "", ""); // then assertThat(result).isTrue(); // verify(mailSendHistoryRepository, times(1)) // .save(any(MailSendHistory.class)); } } mailSendClient는 Mocking하더라도 상태검증을 할 수도 있고, Stubbing하더라도 행위검증을 할 수도 있지 않나요?이 둘의 차이는 Mockist와 Classicist의 차이이지, Mock과 Stub의 차이라고 할 수 없지 않을까요?
-
미해결Practical Testing: 실용적인 테스트 가이드
강사님 유효성 검증의 분리에 대해 궁금한점이 있습니다.
학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요!먼저 유사한 질문이 있었는지 검색해 보세요.서로 예의를 지키며 존중하는 문화를 만들어가요. 저희만의 서비스에 특화된 비즈니스 검증로직은 따로 서비스나 도메인에서 분리해서 검증하라고 하셨는데, 정확히 이해가 가지 않아서 좀더 질문 드립니다.예를 들어, 패스워드 검증 로직이 있다고 하면, 저희만의 서비스는 패스워드 검증을( 영문,특문 혼합 8자이상)이라고 정했을때, 컨트롤러의 요청 부분에서는 @NotBlank를 처리하고, 서비스나 도메인에서 위의 패스워드 검증 로직을 진행하라는 말씀인가요??
-
미해결Practical Testing: 실용적인 테스트 가이드
PK값으로 테스트 할 때 질문입니다.
학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요!먼저 유사한 질문이 있었는지 검색해 보세요.서로 예의를 지키며 존중하는 문화를 만들어가요. 우선, 덕분에 테스트 코드를 작성하는데 많은 도움이 됐습니다! 현재 토이프로젝트 진행 중에 PK 값을 Long 타입으로 두고 @GeneratedValue(strategy = GenerationType.IDENTITY) 이 전략을 사용하니, tearDown을 해도, 전체 테스트에서는 create하고 삭제를 하니, PK인 Long이 1L인 것을 보장을 못하더라구요.그래서 create하는 메서드의 반환을 void로 했다가 Long 타입으로 반환하는데, 이렇게 하는 것도 좋은 코드인가요..?@DisplayName("사용자를 조회하면 사용자의 이름, 직업, 전화번호, 성별을 조회한다.") @Test void getUserInfo() { //given Register register = Register.builder() .name("name") .job(Jobs.STUDENT) .phone("010-0000-0000") .man(true) .build(); Long id = usersService.registerUser(register); //when UserResponse userInfo = usersService.getUserInfo(id); // then assertThat(userInfo.name()).isEqualTo("name"); assertThat(userInfo.job()).isEqualTo(Jobs.STUDENT); assertThat(userInfo.phone()).isEqualTo("010-0000-0000"); assertThat(userInfo.man()).isEqualTo(true); } // 단건 조회 public UserResponse getUserInfo (Long id){ Users user = usersRepository.findById(id). orElseThrow(IllegalArgumentException::new); return UserResponse.of(user); } 입니다!
-
해결됨Practical Testing: 실용적인 테스트 가이드
Fixture 클렌징 관련 질문드립니다.
안녕하세요! 저는 강사님이 말씀해주신 방법들이 아닌 @Sql 어노테이션을 사용해서 모든 테이블을 Truncate하는 방법으로 클렌징을 하고 있었습니다.Truncate는 복구가 안되지만 성능 면에서 Delete보다 빠른 것으로 알고 있는데 제가 사용한 방식도 괜찮은 방법일지, 혹은 발생할만한 문제가 있을지 궁금합니다. teardown.sql-- 모든 제약 조건 비활성화 SET REFERENTIAL_INTEGRITY FALSE; truncate table user_tb; truncate table oauth_tb; truncate table vote_tb; truncate table choice_tb; truncate table vote_item_tb; truncate table place_tb; truncate table review_tb; truncate table review_vibe_tb; truncate table vibe_tb; truncate table place_vibe_tb; truncate table place_food_tb; truncate table food_tb; truncate table participant_tb; -- 모든 제약 조건 활성화 SET REFERENTIAL_INTEGRITY TRUE;
-
미해결Practical Testing: 실용적인 테스트 가이드
현업에서도 TDD를 적극 활용하시는지 궁금합니다.
우빈님 강의에서 말씀해주신 것 처럼 TDD를 활용하면 테스트 코드를 먼저 작성하기 때문에 테스트에 대한 강제(?)할 수 있으며, 엣지 케이스에 대한 식별을 빨리 할 수 있어 많은 장점이 있다고 생각합니다. 제가 생각했을 때는 TDD를 활용하지 못하는 상황은 시간적 여유가 없을 때라고 생각되는데 이 외 다른 이유도 있을까요? 또한, 우빈님께선 평소 TDD를 활용하여 프로덕션 코드를 작성하는지도 궁금합니다.(개발 기간이 부족할 때도 테스트 코드를 무조건 작성하는지도 궁금합니다😀)
-
미해결Practical Testing: 실용적인 테스트 가이드
OrderProduct 테스트에 대해
안녕하세요 강사님먼저 강의에 대해 너무 감사드린다는 말씀 드리고 싶습니다.강의 내용 중 OrderProduct를 생성하는 부분의 책임이 Order에 있게 설계하는 부분에 정말 매력을 느끼고, 유사한 설계 방법들에 대해 공부하려면 어떤 키워드를 알아보면 좋을까요??또한 이 강의를 따라 공부해서 개인적으로 진행중인 프로젝트에 적용하면서 공부하고 있는데, 딱 Order와 OrderProduct같은 관계에서 OrderProduct를 강의에서처럼 생성자가 아닌 정적 팩토리 메소드를 통해 만들어보고자 하였습니다.하지만 여기에서 OrderProdcut의 정적 팩토리 메소드를 테스트하려면 Order가 필요하고, Order를 create하려면 또 OrderProduct가 내부에서 만들어지는 문제가 발생했습니다.이런 경우는 어떻게 해결할 수 있을까요??임의로 Order에 대해 mock으로 생성해서 해결하고는 있는데, 이게 일반적인 방법이 될 수 있을까요?감사합니다!!
-
해결됨Practical Testing: 실용적인 테스트 가이드
혹시 @AllArgsConstructor 를 지양하시는 이유가 빌더 패턴을 사용하기 위함인가요?
private @Builder 를 통해서 객체 생성을 주로 하시는 이유가 Builder 패턴의 장점을 위해서 사용하시는 건지 궁금합니다!
-
해결됨Practical Testing: 실용적인 테스트 가이드
ServiceRequestDto 대신 풀어서 넘기는건 어떻게 생각하시나요?
Controller단의 Dto를 Service 전용 Dto로 변환해서 넘기는 방법을 알려주셨는데Controller단에서 받은 Dto의 컬럼들을 모두 풀어서 Service단 으로 넘겨주는 방법은 어떻게 생각하시는지 궁금합니다.이렇게 하면 순수한 자바코드로 Service단 코드를 작성할 수 있을 거라고 생각하는데 강사님의 생각 알려주시면 감사하겠습니다.
-
해결됨Practical Testing: 실용적인 테스트 가이드
테스트 환경 통합을 위해 커스텀 어노테이션 도입에 관하여
안녕하세요. 테스트 환경 통합 강의를 보다가 궁금한 점이 생겨서 질문하게 되었습니다!강사님께서는 테스트 환경 통합을 위하여 테스트 클래스에서 테스트 환경 추상 클래스(IntegrationTestSupport, ControllerTestSupport)를 상속하는 방식을 사용하셨습니다.ControllerTest에서는 MockMvc, ObjectMapper, @MockBean 처리할 Service들을 protected 필드로 넘겨줄 필요가 있어서 추상 클래스를 사용하는 방식에 대해 되게 좋다고 생각했는데요!Service와 Repository 테스트의 경우에는 그런 공통된 필드들이 필요하지 않기 때문에 추상 클래스가 아닌 커스텀 어노테이션을 생성하여 구성하여도 되지 않을까? 싶어서 질문드리게 되었습니다! @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @ActiveProfiles("test") @SpringBootTest public @interface IntegrationServiceTest { } @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @ActiveProfiles("test") @Transactional @SpringBootTest public @interface RepositoryTest { } 제가 생각한 코드는 위와 같습니다!제가 생각했을 때의 어노테이션으로 테스트 환경을 관리하였을 때의 장점은 자바에서는 다중 상속이 안되기 때문에 조금 더 유연하다고 생각했습니다!강사님께서는 커스텀 어노테이션을 사용하여서 테스트 환경을 통합하는 방식에 대하여 어떻게 생각하시는지 궁금합니다!(강의 너무 유익하게 잘 듣고 있습니다! 새해 복 많이 받으시구 내년에도 화이팅입니다ㅎㅎ)
-
해결됨Practical Testing: 실용적인 테스트 가이드
긴 작업일 경우 트랜잭션을 걸지 말아도 된다는 점이 이해가 잘 안갑니다.
안녕하세요. 테스트 코드를 수강하고 있는 학생입니다. 긴 작업일 경우 트랜잭션을 걸지 말라고 하셨는데. 조회용 트랜잭션이 Repository 단에서 걸린다는 말씀을 하셨는데 Repository의 조회 로직이 수행될 때 트랜잭션이 걸리는 건가요? 뭔가 잘못 이해한거 같기도 해서 질문합니다. 그리고 @RequiredArgsConstructor @Service public class MailService { private final MailSendClient mailSendClient; private final MailSendHistoryRepository mailSendHistoryRepository; public boolean sendMail(String fromEmail, String toEmail, String subject, String content) { boolean result = mailSendClient.sendEmail(fromEmail, toEmail, subject, content); if (result) { mailSendHistoryRepository.save(MailSendHistory.builder() .fromEmail(fromEmail) .toEmail(toEmail) .subject(subject) .content(content) .build() ); return true; } return false; } } 여기서는 Transaction을 걸어줘야 하는게 맞는거 같아서.이 부분도 궁금합니다. 요약저는 서비스 Layer에서 Transaction을 걸어 db작업에서 문제가 발생했을 경우 rollback 되어야 한다고 생각했습니다.강의에서 긴 작업들이 실제로 트랜잭션에 참여하지 않아도 되는데 -> OrderStatisticsService에서는 CUD작업이 아니니깐 Transaction을 안 걸어도 된다.?MailService에서는 Transaction을 걸어줘야 하는게 아닌가요? (Create 작업 수행)조회용 트랜잭션이 Repository 단에서 걸린다.? 뭔지 잘 모르겠습니다.
-
해결됨Practical Testing: 실용적인 테스트 가이드
Optional에 대한 처리
학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요!먼저 유사한 질문이 있었는지 검색해 보세요.서로 예의를 지키며 존중하는 문화를 만들어가요. 강의 잘듣고 있습니다. persistenceLayer 계층 테스트에서 repository 를 테스트할때 Optional<Entity> 형태로 반환하는 함수를 테스트한다고 할때 어떤식으로 테스트를 작성해주어야 되나요? 예를 들어 특정 id를 가진 멤버를 조회한다고 하면 반환값이 Optional<Member>가 될텐데 무조건 찾는 테스트를 한다면 그냥 get()을 붙여서 Optional이 아닌 객체로 꺼내도 되나요?
-
미해결Practical Testing: 실용적인 테스트 가이드
재고 차감 시도 다른 접근법
안녕하세요. 좋은 강의 오늘도 감사히 잘 들었습니다.강사님께서 HashSet 자료구조를 이용하여 중복을 제거하는 방법을 선택하셨지만 전 다른 방법으로 접근해 보았습니다.상품별 counting 한 결과인 productCountingMap 을 이용해보았는데요. 이미 해당 객체는 productNumber 가 중복이 걸러진 상태로 key 값으로 잡혀있고 quantity 가 value 에 정의되어 있어서 이를 그대로 활용해 보았습니다. //상품별 counting Map<String, Long> productCountingMap = createCountingMapBy(stockProductNumbers); //재고 차감 시도 productCountingMap.forEach((key,value)->{ Stock stock = stockMap.get(key); int quantity = value.intValue(); if(stock.isQuantityLessThan(quantity)){ throw new IllegalArgumentException("재고가 부족한 상품이 있습니다."); } stock.deductQuantity(quantity); });감사합니다
-
미해결Practical Testing: 실용적인 테스트 가이드
생성과 수정 API 응답, 그리고 그 응답 Dto를 어떻게 구성할 것인가에 대한고민
안녕하십니까 강사님.저는 이제 5개월차가 된 신입? 백엔드 개발자 입니다.다름이 아니라 , 생성과 수정 API에 대한 응답으로 어떤 정보까지 넘기는것이 적합할지에 대해 고민을 하던 도중 강사님의 생각을 여쭤보고 싶어 질문을 드리게 되었습니다. Q1. 강사님 께서는 생성, 조회 , 수정, 삭제 API의 응답을 각각 어떻게 보내시는지 여쭤보고 싶습니다. 가장 먼저 조회의 경우는 말 그대로 path의 Entity 및 관련된 Entity 정보를 조합하여 응답 DTO로 변환하여 보내고 있습니다. 그런데 나머지 Write Operation에 대한 응답을 어디까지 보내야 하냐가 이슈 입니다.예를들면 엔티티의 생성의 경우 엔티티의 응답 DTO를 보내면 - 프론트에서 별도의 조회 API 호출 없이 바로 프론트가 화면에 뿌려줄 수 있으니깐 저는 생성의 경우에도 조회와 마찬가지로 Entity의 정보를 조합하여 응답 DTO로 변환하여 보내고 있었습니다. 그런데 이러한 부분이 Command Query Sperate 원칙에 어긋나는것 같아, 강사님께서는 혹시 생성한 Entity의 Key만 보내시는지, 아니면 Entity의 정보를 DTO로 변환하여 보내시는지 궁금합니다. 만약 정보를 다 보내신다면 이후에 별도로 조회API를 호출해야 하고 그 또한 비용일텐데 이러한 부분은 어떻게 하시는지 여쭤보고 싶습니다. 이제 수정 API인데요,제가 다룬 비즈니스 로직의 경우 수정 비즈니스 로직이 다양하고 , 각 비즈니스 로직의 경우 다뤄지는 Entity의 종류가 다른 경우였습니다. (중심 Entity는 동일하지만, 연관된 Entity를 누구까지 건드리냐의 차이) 그래서 응답으로 보내기 모호한 점이 첫 번째 이유이고,애초에 수정 후에 프론트 화면에서 그 엔티티의 정보를 보여줄 필요가 없어서 라는 두번째 이유에 의해서 에초에 엔티티의 Id값도 보내지 않고 있었는데요,이 수정 API의 응답을 성렬님은 어떻게 진행하지는지 그 이유가 궁금합니다. 마지막으로 삭제의 경우는 정말, 프론트에게 보낼 응답이 없어도 되는 경우 라고 생각했는데요,팀장님의 의견은 만약에 나중에 삭제한 Entity를 복구하는 요구사항이 추가되는것을 고려하여Id 정도는 넘기자는 의견을 내어주셨습니다.마찬가지로 삭제의 경우도 어떤식으로 수행하시는지 그 이유가 궁금합니다. Q2. 마지막으로 Entity의 ResponseDto의 필드를 어떤식으로 구성하시는지 궁금합니다 예를들면 저의 경우는 API는 프론트와 서버 간의 스펙이라고 생각하고, Entity의 단건조회의 경우는 단건 조회용 ResponseDto를, 전체조회의 경우는 전체 조회용 SummaryResponseDto를 별도로 만들어서 사용하고 있었습니다.(이런식으로 각 상황별 ResponseDto를 별도로 정의하고, 그 안에 관련된 Entity들의 필드를 직접 풀어넣는 방법) 저희 팀장님 께서는 프론트쪽도 일을 해오시다가 , 백엔드쪽 분야로 전향하신 케이스 인데요,그렇다 보니 어떻게 해야 프론트의 생산성이 올라가는지를 고려하시는 분 이셨고,팀장님의 생각은 서버에서 넘겨주는 응답에 일관성이 있어야 그 응답을 사용하는 프론트 측도 학습이 되고 놓치는 부분 없이 생산성이 올라간다는 의견이셨습니다. 그래서 Entity별로 당장 사용하지 않더라도 가능한 모든 필드를 담은 ResponseDto를 하나만 만들고,해당 ResponseEntity의 조합으로 각 API별 응답 Dto를 만들어서 사용하면 ,프론트 측 에서는 일관성 있는 응답값을 사용할 수 있다는 의견이셨습니다.물론 이 방법이 네트워크 패킷의 양을 쓸데없이 증가시킨다는 것을 알고 계시면서도,생산성에 큰 영향을 미치는 부분이라고 생각하셨습니다. 예를들어 다음과 같이 각 Entity의 응답 Dto의 조합별로 API의 ResponseDto를 만들 수 있습니다.ResponseDto{ UserDto{ id : 1, name : “aaa” … // User엔티티의 거의 모든 필드 } ItemDto{ id : 2, name : “bbb”, … // Item엔티티의 거의 모든 필드 }} 저는 이러한 부분에 대해 생각해 본 적이 없이,그냥 제가 “해당 API를 호출하는 화면에서 필요한 정보들만을 담아 |(혹은 여러 화면에서 쓰인다면 여러개를 고려) ResponseDto를 각각 만들어서” 넘겼는데요 강사님께서는 이러한 ResponseDto를 구성하는 부분에 있어서상황별로 필드를 재구성 하여 ResponseDto를 정의하여 사용하시는 편 인지아니면 생산성을 고려하여 각 Entity별 Dto를 만들고, 이들을 조합하여 ReponseDto를 정의하시는 편 이신지 혹은 다른 규칙이 있으신지 궁금합니다. 물론 그렇다고 , 팀장님의 의견에서 전체조회시 사용하는 DTO와 단건조회시 사용하는 DTO가 동일하더라도,전체조회 후 단건조회를 기존 Front가 가지고 있는 값을 그대로 쓰지 말고.,단건 조회용 API를 다시 호출하자 입니다!그저 핵심은 프론트가 다루는 ResponseDto의 일관성을 위해서 입니다 (결론은 생산성을 위해) 항상 좋은 강의,그리고 무엇보다도 강상님의 의견과 고민을 강의에 녹여주셔서정말 감사할 따름입니다. 덕분에 함께 고민하고 많이 배우는거 같습니다. 긴 글 읽어주셔서 감사합니다!
-
미해결Practical Testing: 실용적인 테스트 가이드
정적 팩터리 메서드 사용 기준?
제목 그대로 언제 사용하시는지에 대해 얘기를 나눠보고 싶어 질문 남깁니다.제 경우는 영속성 계층에 새로운 객체가 추가될 때 (RDB에 레코드를 추가할 때) new 키워드를 사용하여 id 값을 생성자로 받지 않는 생성자를 열어두고,존재하는 도메인 엔티티 혹은 영속성 엔티티를 영속성 계층으로부터 불러올 때는 정적 팩터리 메서드를 사용하는데강의를 진행하시면서 습관적으로 생성자 대신 static 메서드를 통해 생성 하시더라구요, 강사님만의 명확한 기준이 있으신지 궁금합니다.