학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요! 먼저 유사한 질문이 있었는지 검색해 보세요. 서로 예의를 지키며 존중하는 문화를 만들어가요. 안녕하세요 우빈님! 테스트 강의 복습 중인데, 다시 들으니깐 너무 재밌네요... 다름 아니라, CQRS 에 따라서 강의를 진행하면서도 Controller와 Service를 CQRS에 따라 분리하고 있습니다. (패키지가 많아지긴하네요..ㅎㅎ..) 그런데 궁금한 부분은 Repsitory쪽인데, JpaRepository를 상속받는 인터페이스들(강의로 예를 들면 ProductRepository, StockRepository, OrderRepository가 있겠네요) 같은 경우인데, sprind data jpa 인터페이스에 CRUD 중에 CD 에 대한 책임을 줄 수는 있겠다 생각했고, U 는 변경감지에 책임을 맡기면 되겠다고 생각했습니다.. 그런데, 쿼리메서드 부분이 모호한데요. 작성했던 쿼리 메서드 같은 경우는 Query에 대한 부분인데 책임을 분리하려고보니, command에 query가 묶여있는 형태더라고요.. 이 부분은 어떻게 나누는지가 궁금합니다.. 제 짧은 지식 선에서는 QueryDSL 로 나눠야 하나 싶지만, 쿼리 메서드라는 편리한 것이 있는데 굳이 돌아가는 것 같다는 느낌이 드네요 제가 굳이 나누려는건지 싶기도 하구요... 조언을 구해봅니다..
안녕하세요 https://inf.run/QwLTR 위의 링크와 연계되는 질문입니다. 복습을 하다 보니 언제 when()으로 stubbing 을 해 줘야할까에 대해 헷갈려져서, 저의 사고 흐름을 정리해봤습니다 컨트롤러에서는 서비스 단 하위로는 모킹을 한다. 모킹하는 객체들은 테스트에서 주 관심사가 아니며, 항상 잘 동작한다고 가정한다. 모킹해오는 객체들은 stubbing을 해주지 않는다면 기본 값들을 반환하는 정책을 따른다. 위 질문 링크의 "판매 상품을 조회한다." 테스트에서는 모킹 객체인 productService의 메소드가 어떤 리턴값을 반환하든 presentation 레이어에서 검증하고 싶은 내용이 아니기 때문에, 검증을 수행하지 않았고, productService.getSellingProducts()에 대한 stubbing도 굳이 필요 없다. "메일 전송 테스트" 에서 mailSendClient.sendEmail()에 대한 stubbing이 필요한 이유 모킹 객체인 mailSendClient.sendMail()이 기본 값 반환 정책이 false이어서, 테스트 하고자 하는 mailService.sendMail()에 영향을 미치기 때문이다. (여기서 기본 값 반환 정책이 true였다면 굳이 stubbing 해주지 않아도 된다 -> "메일 전송 테스트" 에서 검증하고자 하는 대상이 아니기 때문에) 이런식으로 테스트에 검증하고자 하는 대상에 집중하다 보면 모든 동작을 제대로 stubbing했다고 보장하기 어려워 진다 -> Mockist의 치명적인 단점 제가 정리해 본 내용이 적절한지 알려주시면 감사합니다. 테스트의 세계는 정말 헷갈리네요..
안녕하세요 선생님 질문이 생겨서 글 남깁니다.! 선생님이 생각하시는 가장 이상적인 테스트 코드 범위는 어디 까지인가요?? 예를들어 controller,service,repository가 있다고 가정하고 선생님 강의처럼 각각 레이어별로 테코를 짜고 service 쪽도 repo를 mock처리하여 단위테스트까지도 진행 하여야하나요? 제 질문을 정리하자면 controller,service,repository 각각 단위테스트 작성후 service + repo로 통합테스트 하는게 옳은 이상적인 범위인가 궁금합니다 감사합니다
private List<Product> findProductsBy(List<String> productNumbers) { return productRepository.findAllByProductNumberIn(productNumbers); } 그냥 이렇게 바로 리턴 해도 되지 않나요??
두 가지 궁금증이 생겨 질문드립니다!! Mock과 Stub에서 혼란을 느끼는지? Mock & Stub 에 대한 이해를 하였는지? // OrderTest.java import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; public class OrderTest { @Test void 주문_총_금액을_계산한다() { Product apple = new Product("사과", 1000); Product banana = new Product("바나나", 2000); Order order = new Order(); order.addProduct(apple); order.addProduct(banana); assertEquals(3000, order.totalPrice()); } } // OrderTest.java import org.junit.jupiter.api.Test; import static org.mockito.Mockito.*; import static org.junit.jupiter.api.Assertions.*; public class OrderTest { @Test void 주문_총_금액을_계산한다_Product_Mock_사용() { Product apple = mock(Product.class); Product banana = mock(Product.class); when(apple.getPrice()).thenReturn(1000); when(banana.getPrice()).thenReturn(2000); Order order = new Order(); order.addProduct(apple); order.addProduct(banana); assertEquals(3000, order.totalPrice()); } } 두 테스트에서 생각을 정리하다 보니 저는 마틴 파울러의 test double의 stub 과 mock 에 대한 개념보다 TTD or BDD 스타일의 테스트 코드를 작성하다가 테스트의 편의성을 위해 Mokito을 통한 Mock 테스트 를 먼저 접하게 된 후 마틴 파울러의 test double의 개념을 접하게 되었습니다. 마틴 파울러의 Mock 과 Stub 테스트에서 혼란스러운 이유 테스트 코드를 작성하다보면 자연스럽게 then에 해당하는 부분 은 대부분 상태(값)을 검증하는 테스트 를 위주로 테스트 코드를 작성하게 되는거 같습니다. 주문_총_금액을_계산한다() -> 단위 테스트로 상태(값)을 검증 주문_총_금액을_계산한다_Product_Mock_사용() -> 나는 Mockito의 mock 테스트 로 상태(값)을 검증 test double stub -> 상태(값) 검증 mock -> 행동 검증 위 와 같이 상태(값) 을 검증하는 테스트를 하다보니 stub 테스트 와 Mockito 의 mock을 사용한 테스트 을 동일시 보게 된거같습니다. Mockito의 mock 테스트 의 개념과 test double의 mock 테스트 가 동일한 개념이 아니다. Mokito의 mock을 사용하여 상태(값)을 검증하는 테스트를 하다보니 test double의 stub 테스트 를 Mock 테스트 하였다라고 생각한게 아닌가? 테스트 케이스 stub 과 mock 테스트 구별하기 주문_총_금액을_계산한다() 해당 테스트는 실제 객체 를 이용하여 상태(값)에 대한 검증 을 한다. -> Stub 테스트 주문_총_금액을_계산한다_Product_Mock_사용() 해당 테스트는 Product 를 Mock 하여, order의 totalPrice 을 검증 한다. -> Mock?, Stub? 주문_총_금액을_계산한다_Product_Mock_사용()를 어떻게 바라 볼 것인가? test double의 mock 테스트를 준비 하였지만 검증 부분을 잘못하였다. test double의 stub 테스트를 실제 객체가아닌 가짜객체로 테스트 하였다. @Test void 주문_총_금액을_계산한다_Product_Mock_사용() { // given Product apple = mock(Product.class); Product banana = mock(Product.class); when(apple.getPrice()).thenReturn(1000); when(banana.getPrice()).thenReturn(2000); Order order = new Order(); order.addProduct(apple); order.addProduct(banana); // when int total = order.totalPrice(); // then verify(apple).getPrice(); // apple.getPrice()가 호출되었는지 검증 verify(banana).getPrice(); // banana.getPrice()가 호출되었는지 검증 } 주문_총_금액을_계산한다_Product_Mock_사용()를 위와 같이 수정한다면 test double에서 이야기하는 mock 테스트이지 않을까 생각이 듭니다. 물론 모든 테스트를 test double의 Mock, Stub 테스트라는 틀에 맞춰 작성해한다는 아니라고 생각이 듭니다. 주문_총_금액을_계산한다_Product_Mock_사용()가 마틴 파울러가 이야기하는 test double의 개념 에서 어떻게 생각해 볼 것인가? 에대한 궁금증 우빈님의 생각이 궁금 하기도 합니다. 제가 잘 이해를 하였는지 확인이 필요하여 질문드립니다.
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요, 리액트 학습 중에 궁금한 게 있어서 질문드려요. 기본 path 가 아닌 라우트로 바로 접속을 할때, html을 받으면 라우팅이 이뤄지구 useeffect로 api 요청이 가면서 페이지 렌더링이 이뤄지는건가요?
안녕하세요, 6:13초 쯤에 Mock에 대한 예시로 앞에서 작성했던 "when 해서 sendMail 했을 때 파라미터 4개를 넘겨줬을 때 어떤 값을 리턴함" 을 말씀해주셨는데요, 이게 stub에 가까운게 아닌가란 의문이 들었습니다. 마틴 파울러의 글을 보면 Mock은 결국 호출 여부나 호출 횟수 같은 것을 검증하는 것 같더라구요. 뭔가 이해가 잘 안돼서 질문을 남깁니다. 감사합니다.
안녕하세요~ 강의가 넘 좋습니다!! 넘 재밌게 잘 들었어요~ msa프로젝트에서 kafka, feignClient는 테스트를 어떻게 진행하는지 궁금합니다. (서비스단 테스트시 카프카를 mocking해서 테스트하는 것을 여쭙는게 아닙니당 ㅎㅎ) 저 자체는 테스트하지 않으시는지..? 실제로는 서비스 여러개 띄워놓고 메세지 발행이나 api 통신이 되는지 확인하고 있는데 테스트로도 할 수 있는 방법이 있나해서요. 현업에서는 어떻게 하는지 궁금합니다~
@Test void calculateTotalPrice() { 위에 이미지 처럼 테스트에서 검증 후 , 아래처럼 public int calculateTotalPrice() { return beverages.stream().mapToInt(Beverage::getPrice).sum(); } 로 리팩토링 진행하셨는데 테스트코드에서 검증 통과받으면, 프로젝트 코드에서 리팩토링 된 부분은 천하무적 이라고 생각하면 되나요 ? 이때 발생하게 되는 변수는 없을련지,,,, 궁금합니다!
안녕하세요 테스트 케이스 세분화하기 강의에서 // CafeKiosk.java public void add(Beverage beverage, int count) { if (count < 0) { throw new IllegalArgumentException("음료는 1잔 이상 주문하실 수 있습니다."); } for (int i = 0; i < count; i++) { beverages.add(beverage); } } 해당 메소드에 대한 단위테스트를 만드는데 궁금증이 생겨서 질문을 남겨봅니다. [질문] 경계값(0, -1)에 대해서도 테스트 케이스를 세분화해서 만들어야 되는건가? // 예시 // 경계값 0에 대한 테스트 함수 @Test void addZeroBeverages() { ... (생략) } // 경계값 -1에 대한 테스트 함수 @Test void addNegativeOneBeverages() { ... (생략) } 아니면 테스트 케이스 하나를 만들어서 그안에 값을 변경하면서 테스트해야되는건지 궁급합니다! // 예시 @Test void addZeroAndNegativeOneBeverages() { ... (생략) // 0값 체크 후 테스트 통과하면 1로 고쳐서 테스트 assertThatThrownBy(() -> cafeKiosk.add(americano, 0)) .isInstanceOf(IllegalAccessError.class) .hasMessage("음료는 1잔 이상 주문하실 수 있습니다."); }
학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요! 먼저 유사한 질문이 있었는지 검색해 보세요. 서로 예의를 지키며 존중하는 문화를 만들어가요. 안녕하세요 테스트 코드에 대해 고민이있는 학생입니다. 단위테스트에 대한 질문을 하고싶습니다! 저는 단위테스트를 h2를 이용하지않고 fake repo를 만들어서 테스트하였고 통합테스트할때는 h2를 이용해서 테스트하였는데 테스트 강의하시면서 강조하셧던 부분이 테스트하는것도 비용이다! 그래서 스프링서버를 띄우는것을 extends해서 통합하여 관리하셨던것이 굉장히 큰 도움이되었습니다. 그렇다면 단위테스트할때 fake Repo를 커스텀하는 노력만 조금 들인다면 단위 테스트에대한 속도도 더빨라질거라 생각하는데 어떻게 생각하시나요? fake repo를 만들때 list, map, set 중에 저는 map을선택하였는데 혹시 어떤것을 사용하시는지? 테스트 패키지 구조를 통합, 단위 라는 패키지를따로만들어서 넣는것보다 alt + insert로 만들기 쉽게 같은공간에 단위,통합이 존재하게하면서 Test, IT 라는 네이밍으로 클래스를만들고있는데 ex) OrderServiceTest, OrderServiceIT 우빈님은 어떻게 통합과 단위 패키지구조를 설계하시는지 궁금합니다.
학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요! 먼저 유사한 질문이 있었는지 검색해 보세요. 서로 예의를 지키며 존중하는 문화를 만들어가요. 안녕하세요. 개인 프로젝트를 진행하다 궁금한 점이 있어 질문드립니다. 현재, 서로 다른 두 트랜잭션이 동시에 실행될 때 발생할 수 있는 동시성 문제를 해결하기 위해 락을 적용해두었습니다. 테스트 코드에서는 락이 없는 경우에는 문제 상황이 발생하고, 락 적용 시에는 정상 작동함을 보여주고자 합니다. 인터넷에서 관련 자료를 찾아본 결과, Executor 와 CountDownLatch 를 활용하여 동시성 문제를 테스트하는 방식을 많이 사용하길래, 저도 이를 적용해 테스트를 구성하려 하고 있습니다. 멀티스레딩 환경에서는 실행 순서가 보장되지 않으므로, 운이 나쁘면 두 트랜잭션이 순차적으로 실행될 수도 있다고 생각했고 실행 순서를 제어하여 문제가 발생할 수 있는 상황을 코드로 만들어야 한다고 생각했습니다. 그러나 Executor 와 CountDownLatch 만으로는 트랜잭션 단위로 묶인 작업들의 실행 순서를 제어하기 어려워, 원하는 동시성 문제 시나리오를 재현하는 데 한계가 있었습니다. wait , notify 등의 스레드 제어 메서드를 활용하면 원하는 실행 순서를 만들 수 있을 것 같지만, 이것이 최선의 방법인지 고민이 되어 질문드립니다. 선생님께서는 동시성 문제 테스트를 진행할 때, 실행 순서를 제어하여 문제가 발생하는 시나리오를 인위적으로 만들고 이런 상황에서도 정상 작동함을 확인하시나요? 아니라면 동시성 문제를 테스트할 때 어떤 방법을 사용하시는지 궁금합니다