묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결Practical Testing: 실용적인 테스트 가이드
실무에서 연관관계 매핑에 대해 질문이 있습니다.
학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요!먼저 유사한 질문이 있었는지 검색해 보세요.서로 예의를 지키며 존중하는 문화를 만들어가요. 실무에서는 연관관계 매핑이 하나의 애그리게이트에서는 사용하되 다른 에그리게이트와 매핑시에는 엔티티 매핑이 아닌다른 에그리게이트의 id로 매핑한다고 하더라구요. 엔티티 매핑이 ManyToOne 관계에서 Many쪽에 one의 id로 매핑을 매핑하면 되는데, ManyToMany 관계에서의 다른 애그리게이트 관계와의 연관 관계 매핑이 아닌 id로는 어떻게 해결하시는 궁금합니다.
-
해결됨쥬쥬와 함께 하루만에 끝내는 스프링 테스트
Mock 객체 사용법
아직 mock 사용법이 이해가 안가는데 실제로 db에 저장도 안되고 jpa repository 호출도 안되는 건가요? db가 올라간 도커를 내려도 잘 되네요
-
미해결따라하며 배우는 리액트 A-Z[19버전 반영]
마이너스버튼 테스트
test("Prevent the -,+ button from being pressed when the on/off button is clicked",()=>{ render(<App />); const onOffButtonElement = screen.getByTestId("on/off-button"); // click onOffButtonElement button fireEvent.click(onOffButtonElement); const plusButtonElement = screen.getByTestId("plus-button"); expect(plusButtonElement).toBeDisabled(); })on/off버튼을 통해 플러스와 마이너스 버튼의 클릭시 disable속성을 추가하는 과정에서 app.test.js에 테스트항목에 마이너스에 대한 내용을 안적어도 무관한가요?플러스가 잘작동하면 마이너스도 잘 작동할 것이기 때문인가요?
-
해결됨실무에 바로 적용하는 프런트엔드 테스트 - 1부. 테스트 기초: 단위・통합 테스트
상태 검증과 행위 검증에 대해서 질문이 있어 남기게 되었습니다!
현재 하고 있는 프로젝트에 테스트 코드를 연습하고 있는데 상태 기반 검증은 보통 "custom hook"과 같이 비즈니스 로직에 하고, 행위 검증은 컴포넌트의 이벤트 처리와 같은 상황에 하고 있는데 이렇게 진행하는게 맞는 건지에 대해서 궁금해서 질문을 남기게 되었습니다!vitest에서는 stub과 mock과 같은 테스트 더블을 완벽하게 구별짓지 않는다고 생각하고 있는데 맞을까요? 추가적으로 공부를 해보았을 때 상태 기반 검증은 stub, fake 행위 기반 검증은 mock, spy로 하는 것이라고 나누었는데 이것이 맞는 내용인가요?
-
미해결Java/Spring 테스트를 추가하고 싶은 개발자들의 오답노트
컨트롤러에서 받는 request dto에 대해 궁금한점
강사님께서 짜주신 코드에서는 컨트롤러에서는 요청을 받는 DTO를 Domain까지 전파해서 활용하시던데, 보통 코드를 보면 컨트롤러에서 받은 Request Dto -> Domain으로 변환 후에 비즈니스 로직을 처리하는 코드도 많이 봤어서 어떻게 옳고 그른지 궁금합니다.또한 Request Dto를 도메인에서 파라미터로 받아서 활용해도 되는지도 궁금하구요.
-
미해결Practical Testing: 실용적인 테스트 가이드
Spy 질문입니다.
안녕하세요 강사님.강사님 강의를 듣고 실무에 적용을 해보고 있습니다.예를 들어 A Service 테스트를 위한 테스트 코드에서Class AService { @Autowired private ARepository arepository; public void methodA() { arepository.procedure(); arepository.two(); } }위와 같이 구성이 되어 있는데 methodA에서 리포지토리의 procedure만 모킹처리를 하고싶습니다.테스트코드를 대략 아래와 같이 @Spy를 사용해서 의존성 주입을 하는데 작동이 안되어 문의드려요. 제가 한 방식이 잘못된걸까요?@ExtendWith(MockitoExtension.class) class Test { @InjectMocks; private AService aservice; @Spy private ARepository arepository; @Test void test() { doReturn("OK").when(arepository).procedure(); aservice.methodA(); } }
-
해결됨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;
-
미해결쥬쥬와 함께 하루만에 끝내는 스프링 테스트
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 주소 좀 알려주실 수 있나요?노션 자료가 좋긴한데 코드가 없어서 개인적으로 조금 힘드네요
-
해결됨Practical Testing: 실용적인 테스트 가이드
반환 타입이 void인 메서드에 대한 질문이 있습니다.
안녕하세요 강의 잘 듣고 있습니다! 위 사진처럼 Service 레이어에서 반환 타입이 void인 메서드의 경우, assertJ로 검증하는 방법이 있나요? 해당 메서드에서 create 작업을 수행하지만 굳이 생성된 객체를 응답할 이유가 없어서요!예전에 임시로 반환 타입을 바꿔서 생성된 객체를 검증하는 식으로 테스트를 작성하면 된다는 얘기를 들었는데, 결국 void로 되돌리게 되면 테스트가 실패하니까 테스트를 주석 처리할 수 밖에 없었거든요...이렇게 하게 되면 테스트 코드를 작성하는 의미도 좀 퇴색되는 것 같아서 고민이 됩니다!일단은 급한대로 then은 비워두었습니다만 이렇게 하는 게 좋은 방법일까요?
-
미해결Practical Testing: 실용적인 테스트 가이드
Order에서 orderProducts 테스트하는 방법이 궁금합니다.
package sample.cafekiosk.domain.order; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.test.context.ActiveProfiles; import sample.cafekiosk.domain.product.Product; import sample.cafekiosk.domain.product.ProductRepository; import sample.cafekiosk.domain.product.ProductSellingStatus; import sample.cafekiosk.domain.product.ProductType; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; import static org.assertj.core.groups.Tuple.tuple; import static sample.cafekiosk.domain.product.ProductSellingStatus.*; import static sample.cafekiosk.domain.product.ProductType.HANDMADE; @ActiveProfiles("test") @DataJpaTest class OrderRepositoryTest { @Autowired private OrderRepository orderRepository; @Autowired private ProductRepository productRepository; @DisplayName("원하는 날짜와 주문 상태로 주문들을 가져온다.") @Test void findOrdersBy() { //given LocalDateTime registeredDateTime1 = LocalDateTime.of(2024, 3, 2, 12, 0); LocalDateTime registeredDateTime2 = LocalDateTime.of(2024, 3, 9, 12, 0); Product product1 = createProduct(SELLING, HANDMADE, "아메리카노", 4000, "001"); Product product2 = createProduct(HOLD, HANDMADE, "카페라떼", 4500, "002"); Product product3 = createProduct(STOP_SELLING, HANDMADE, "팥빙수", 7000, "003"); List<Product> products = List.of(product1, product2, product3); productRepository.saveAll(products); Order order1 = createOrder(registeredDateTime1, products); Order order2 = createOrder(registeredDateTime2, products); List<Order> orders = List.of(order1, order2); orderRepository.saveAll(orders); //when LocalDate findDate = LocalDate.of(2024, 3, 2); List<Order> findOrders = orderRepository.findOrdersBy(findDate.atStartOfDay(), findDate.atStartOfDay().plusDays(1), OrderStatus.PAYMENT_COMPLETED); //then Assertions.assertThat(findOrders).hasSize(1) .extracting("registeredDateTime", "orderProducts", "orderStatus") .containsExactlyInAnyOrder( tuple(registeredDateTime1, products, OrderStatus.PAYMENT_COMPLETED) ); } private Order createOrder(LocalDateTime registeredDateTime1, List<Product> products) { return Order.builder() .orderStatus(OrderStatus.PAYMENT_COMPLETED) .registeredDateTime(registeredDateTime1) .products(products) .build(); } private Product createProduct(ProductSellingStatus sellingStatus, ProductType type, String name, int price, String productNumber) { return Product.builder() .productNumber(productNumber) .type(type) .sellingStatus(sellingStatus) .name(name) .price(price) .build(); } }안녕하세요. 우빈님OrderRepository의 findOrdersBy() 테스트는 직접 작성하라고 하셔서 테스트를 작성하다가 궁금한 점이 생겨 질문 남깁니다. 첫 번째는 Order의 orderProducts를 테스트할 때, products가 프록시 객체로 넘어와서 테스트하지 못하는 거 같습니다.현재 코드는 테스트가 실패하는 코드고, extracting에서 "orderProducts"를 제외하면 성공하는 테스트가 됩니다.이럴 때는 어떻게 해결해야 할지 궁금합니다. 두 번째 질문은 제가 작성한 테스트 코드 구조에서 개선할 사항이 있는지 궁금합니다. 강의 잘 보고 있습니다.감사합니다.
-
해결됨실무에 바로 적용하는 프런트엔드 테스트 - 1부. 테스트 기초: 단위・통합 테스트
navigate 관련 테스트에서 질문있습니다!
버튼을 눌렀을 때, navigate 하는 경우를 테스트할 때는 클릭 시 함수가 호출되었는지에 대한 테스트만 하면 되는 건가요??혹시, 특정 경로로 잘 이동되었는지에 대한 테스트를 하는 방법이 있는지 여부와 해당 테스트가 존재한다면 통합테스트인건지 단위 테스트인건지 궁금합니다! 그리고, 그런 테스트가 존재한다면 어떻게 assert할 수 있는지도 알고 싶습니다!
-
미해결스프링부트 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 [제목을 입력해 주세요]] ]
-
해결됨따라하며 배우는 리액트 A-Z[19버전 반영]
리액트 서버 실행 오류
리액트 설치 npx create-react-app ./ 이후리액트 최초 시작 시 npm run start가 작동하지 않습니다.위와 같은 오류가 발생하여, 아래와 같은 해결 방법들을 실행해보았습니다. 하지만, 위의 코드를 모두 실행했음에도 동일한 오류가 계속해서 발생합니다. node.js와 npm의 버전은 이러합니다. 폴더는 현재 강의자료 코드 폴더 내에 study라는 새로운 폴더를 만들어, 그 안에 리액트를 설치했습니다.프로젝트를 3번 정도 삭제하고 다시 설치했음에도 동일한 오류가 발생합니다. 어떻게 하면 좋을까요? 🥲 VSCode를 재시작하니 서버가 실행되었는데, App.js의 수정사항이 반영되지 않아 다시 VSCode를 재시작했더니 또 동일한 오류가 납니다...
-
미해결2시간으로 끝내는 프론트엔드 테스트 기본기
안녕하세요. 질문 있습니다.
섹션3 recoil을 테스트하는 방법 3:50에cy.url().should('include','/');를 통해서 root page로 잘 이동하는지 확인한다고 하신부분에서,'/'는 어떤 페이지에서든 include가 되어 테스트가 통과될것 같은데 혹시 rootpage를 검증하기위한 다른 방법은 없을까요?
-
미해결쥬쥬와 함께 하루만에 끝내는 스프링 테스트
[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에 접속은 되는데 안에 초기 데이터가 들어가지를 않는데 어떤게 문제이고 어떻게 해결할 수 있을까요?
-
미해결스프링부트 JUnit 테스트 - 시큐리티를 활용한 Bank 애플리케이션
equals와 longValue 관련 질문드립니다
[질문]제가 담당했던 업무에서는 Long 값을 비교하는 일이 거의 없어서 이 챕터에서 생각을 못 했었던 부분을 알게 되어 좋았습니다.관련 자료를 찾아보다가 equals 메서드에서는 Long 타입일 경우 .longValue();로 체크하는 로직을 보게되었습니다. public boolean equals(Object obj) { if (obj instanceof Long) { return value == ((Long)obj).longValue(); } return false; } 은행권 같은 실무에서는 equals와 longValue 둘이 어떻게 사용하는지 궁금합니다. [참고 자료] https://www.baeldung.com/java-compare-long-values
-
미해결Practical Testing: 실용적인 테스트 가이드
현업에서도 TDD를 적극 활용하시는지 궁금합니다.
우빈님 강의에서 말씀해주신 것 처럼 TDD를 활용하면 테스트 코드를 먼저 작성하기 때문에 테스트에 대한 강제(?)할 수 있으며, 엣지 케이스에 대한 식별을 빨리 할 수 있어 많은 장점이 있다고 생각합니다. 제가 생각했을 때는 TDD를 활용하지 못하는 상황은 시간적 여유가 없을 때라고 생각되는데 이 외 다른 이유도 있을까요? 또한, 우빈님께선 평소 TDD를 활용하여 프로덕션 코드를 작성하는지도 궁금합니다.(개발 기간이 부족할 때도 테스트 코드를 무조건 작성하는지도 궁금합니다😀)
-
해결됨실무에 바로 적용하는 프런트엔드 테스트 - 1부. 테스트 기초: 단위・통합 테스트
테스트 실행 중 에러가 납니다.
vitest 를 통해 실행하면 계속 위와 같은 에러가 나는데, 어떤 이유일까요? 커멘드라인을 이용해서 npm run test 를 입력하면 그 때는 테스트가 잘 이뤄집니다.
-
해결됨Practical Testing: 실용적인 테스트 가이드
@SQLRestriction으로 논리적 삭제 필드에 대한 tearDown에 대해 궁금합니다.
안녕하세요.강의를 들은 후 테스트 코드 작성을 연습하고 있습니다.엔티티에서 Soft delete를 위한 필드(isDeleted)가 정의되어 있습니다.Soft delete가 된 데이터는 조회할 필요가 없기 때문에 엔티티에 @SQLRestriction("is_deleted = false")를 정의했습니다.테스트 코드에서 해당 어노테이션 때문에 tearDown() 메서드 동작시 문제가 발생했습니다..deleteAllInBatch()가 실행될 때, where 조건이 포함되기 때문에 데이터가 삭제되지 않습니다. 상품 목록 조회에 대한 테스트 코드를 작성할 때, soft delete 된 데이터는 빠지고 정상적인 데이터만 조회되는지 보려고 isDeleted = true 값을 준 테스트 데이터도 생성해서 테스트 코드를 작성했습니다. 해당 경우에는 어떤식으로 테스트 코드를 작성해야 할까요? isDeleted = true 테스트 데이터를 만들지 않는다.@SQLRestriction("is_deleted = false") 를 사용하지 않고, 쿼리 조회 시 IsDeletedTrue 조건을 주도록 한다.위 방법이 아닌 Best Practice가 있는지 궁금합니다. 아래는 테스트 코드 예시 입니다.@SQLRestriction("is_deleted = false") 적용된 엔티티 예시입니다.@Entity @SQLRestriction("is_deleted = false") @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Product extends BaseDateTimeEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "product_id") private Long id; @Column(length = 50) private String name; private Boolean isDeleted; @OneToMany(mappedBy = "product", cascade = CascadeType.ALL) private List<ProductOption> productOptions = new ArrayList<>(); // ... 중략 }@Entity @SQLRestriction("is_deleted = false") @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class ProductOption extends BaseDateTimeEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "product_option_id") private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "product_id") private Product product; @Column(length = 30) private String name; private Boolean isDeleted; // ... 중략 } isDeleted = true 테스트 데이터를 포함한 테스트 코드 예시입니다.class ProductServiceTest extends ServiceTestSupport { @Autowired private ProductRepository productRepository; @AfterEach void tearDown() { productOptionRepository.deleteAllInBatch(); productRepository.deleteAllInBatch(); } @Test @DisplayName("상품 목록을 조회한다.") void getSellingProducts() throws Exception { // given ProductOption productOption1 = createProductOption("옵션1", false); ProductOption productOption2 = createProductOption("옵션2", false); ProductOption productOption3 = createProductOption("옵션3", false); ProductOption productOption4 = createProductOption("옵션4", true); // isDeleted = true ProductOption productOption5 = createProductOption("옵션5", false); ProductOption productOption6 = createProductOption("옵션6", true); // isDeleted = true Product product1 = createProduct("상품1", false, List.of(productOption1, productOption2)); Product product2 = createProduct("상품2", false, List.of(productOption3, productOption4)); Product product3 = createProduct("상품3", true, List.of(productOption5, productOption6)); // isDeleted = true productRepository.saveAll(List.of(product1, product2, product3)); // ... 중략 // when List<product> products = productService.getSellingProducts(); // then // ... 중략 } // ... 중략 } deleteAllInBatch() 메서드가 실행된 후 로그 입니다.Hibernate: delete from product_option where ( product_option.is_deleted = false ) Hibernate: delete from product where ( product.is_deleted = false ) org.springframework.dao.DataIntegrityViolationException: JDBC exception executing SQL [delete from product where (product.is_deleted = false)] [Referential integrity constraint violation: "FKN4HMM6EX1VGN60C6UIQTE400F: PUBLIC.PRODUCT_OPTION FOREIGN KEY(PRODUCT_ID) REFERENCES PUBLIC.PRODUCT(PRODUCT_ID) (CAST(3 AS BIGINT))"; SQL statement: delete from product where (product.is_deleted = false) [23503-224]] [n/a]; SQL [n/a]; constraint ["FKN4HMM6EX1VGN60C6UIQTE400F: PUBLIC.PRODUCT_OPTION FOREIGN KEY(PRODUCT_ID) REFERENCES PUBLIC.PRODUCT(PRODUCT_ID) (CAST(3 AS BIGINT))"; SQL statement: delete from product where (product.is_deleted = false) [23503-224]] 감사합니다.