묻고 답해요
160만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결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]] 감사합니다.
-
미해결Java/Spring 테스트를 추가하고 싶은 개발자들의 오답노트
Util성 클래스와의 비교
안녕하세요 좋은 강의 만들어 주셔서 감사합니다. 많은 분들이 비슷한 질문을 해주신 것으로 생각되는데, Util성 클래스와 Holder인터페이스를 구현한 구체클래스의 의존주입의 사용 기준에 대해 여쭤보려고 합니다. 강의에서 예로 들어주신 SystemClockHolder의 경우 많은 예제에서 Util클래스로 만들어 사용할 것이라고 생각됩니다.하지만 이렇게 되면 강의에서 말씀해주신 것처럼 메소드 내부에 사용자가 예측할 수 없는 값이 들어가게 되어 테스트하기 어려워지는 신호가 될 수 있다고 생각합니다. 반면 이러한 Holder가 너무 많아질 경우 서비스 계층에서 의존주입 받아야할 Holder가 너무 많아지지는 않을까 하는 고민도 되었습니다. 강사님께서는 어떤 기준으로 Util클래스와 인터페이스 기반의 의존주입 클래스를 구분하시는지 궁금합니다.
-
해결됨Practical Testing: 실용적인 테스트 가이드
강사님은 테스트를 어떻게 하시는지 궁금합니다.
학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요!먼저 유사한 질문이 있었는지 검색해 보세요.서로 예의를 지키며 존중하는 문화를 만들어가요. Classicist에 대해서 궁금해서 질문드립니다.현업 또는 강사님 혼자서 컨트롤러만 테스트 할 경우 서비스 레이어를 mock, stub을 사용하시는지,아니면 Fake Service 및 Fake Repository를 구현 후 컨트롤러 테스트를 하시는지 궁금합니다.Classicist을 추구하면 외부 환경만 Mock을 사용해서 테스트를 해야하는 지 아니면 최대한 Mock을 지양하지만 컨트롤러 테스트 같은 경우에는 Mock을 사용하나요?
-
해결됨실무에 바로 적용하는 프런트엔드 테스트 - 1부. 테스트 기초: 단위・통합 테스트
안녕하세요. 훅 테스트 질문이 있습니다!
예제에서 말씀해주신것처럼,result.current.setState() 를 호출해서 act() 를 통해 업데이트 된 상태를 검증하는 방법을 말씀해주셨는데요. 훅 내부 이펙트에서 상태를 업데이트하는 로직을 검증하려면 어떤 식으로 검증해야할까요? export const useDarkMode = (defaultTheme = THEME["LIGHT"]) => { const [theme, setTheme] = useState(defaultTheme); const changeTheme = (type: keyof typeof THEME) => { setTheme(THEME[type]); }; useLayoutEffect(() => { const mediaQueryList = window.matchMedia("(prefers-color-scheme: dark)"); const changeListener = ({ matches }: MediaQueryListEvent) => { setTheme(THEME[matches ? "DARK" : "LIGHT"]); }; mediaQueryList.addEventListener("change", changeListener); return () => { mediaQueryList.removeEventListener("change", changeListener); }; }, []); return { theme, changeTheme, }; }; 위 useDarkMode() 훅 내부 useLayoutEffect() 에서window.matchMedia 의 change 이벤트를 감지하면, setTheme() 하도록 설계되어 있는데요. window.matchMedia 함수의 matches 결과를 true 로 모킹하고,window.matchMedia.dispatchEvent('change') 를 일으켜 검증을 시도해보았는데요.생각처럼 검증이 되지 않는 것 같습니다.ㅠ 혹시 이렇게 검증을 시도하는 것이 맞는지. 검증하는게 맞는지. 여쭤봐도 될까요? 감사합니다.
-
미해결Practical Testing: 실용적인 테스트 가이드
OrderProduct 테스트에 대해
안녕하세요 강사님먼저 강의에 대해 너무 감사드린다는 말씀 드리고 싶습니다.강의 내용 중 OrderProduct를 생성하는 부분의 책임이 Order에 있게 설계하는 부분에 정말 매력을 느끼고, 유사한 설계 방법들에 대해 공부하려면 어떤 키워드를 알아보면 좋을까요??또한 이 강의를 따라 공부해서 개인적으로 진행중인 프로젝트에 적용하면서 공부하고 있는데, 딱 Order와 OrderProduct같은 관계에서 OrderProduct를 강의에서처럼 생성자가 아닌 정적 팩토리 메소드를 통해 만들어보고자 하였습니다.하지만 여기에서 OrderProdcut의 정적 팩토리 메소드를 테스트하려면 Order가 필요하고, Order를 create하려면 또 OrderProduct가 내부에서 만들어지는 문제가 발생했습니다.이런 경우는 어떻게 해결할 수 있을까요??임의로 Order에 대해 mock으로 생성해서 해결하고는 있는데, 이게 일반적인 방법이 될 수 있을까요?감사합니다!!
-
해결됨스프링부트 JUnit 테스트 - 시큐리티를 활용한 Bank 애플리케이션
계좌번호를 Long 타입으로 하는 이유가 무엇일까요?!
기초적인 질문일 수도 있으나 궁금합니다...
-
해결됨스프링부트 JUnit 테스트 - 시큐리티를 활용한 Bank 애플리케이션
[정보공유] Hibernate 로그 작동 안하시는 분들!!
Hibernate 로그 작동 안하시는 분들 중에 저처럼 Spring-boot:3.0.0 쓰시는 사람 계시다면 도움 될 겁니다! 기존 강사님 application-test.ymllogging: level: '[shop.mtcoding.bank]': DEBUG '[org.hibernate.type]': TRACE기존의 org.hibernate.type: TRACE를 org.hibernate.orm.jdbc.bind: TRACE 이걸로 대체해주시면 작동 될 겁니다!!수정된 application-test.ymllogging: level: org.hibernate.orm.jdbc.bind: TRACE shop.mtcoding.bank: DEBUG왜냐하면 원인이 Spring-boot3 부터 hibernate6 사용하기 때문입니다. 따라서 Spring-boot3에서는 hibernate6의 log level 설정하는 방법으로 yml을 정의해야 제대로 로그가 찍힙니다. 자세한 것은 아래 링크를 확인해보시면 도움 될 것 같습니다😚. 출처: https://thorben-janssen.com/hibernate-logging-guide/#log4j-configuration-for-hibernate-4-5-and-6
-
해결됨실무에 바로 적용하는 프런트엔드 테스트 - 1부. 테스트 기초: 단위・통합 테스트
prop이나 state 값을 검증하지 않는다는 의미가 궁금합니다!
const textField = screen.getByPlaceholderText('텍스트를 입력해 주세요.'); expect(textField).toHaveClass('my-class');이부분에서 className이란 내부 props, state 값을 검증하는 게 아닌가 싶어서 질문을 드렸습니다. 물론, className에 따라 변경되는 DOM을 파악한다는 의미로도 해석이 될 수는 있을 것 같긴 하지만 더 정확한 문맥을 알고 싶어서 질문드렸습니다..!
-
해결됨스프링부트 JUnit 테스트 - 시큐리티를 활용한 Bank 애플리케이션
UserControllerTest 테스트 실패 문의
안녕하세요, 강사님!강사님 쉬운 설명 덕분에 재밌게 강의 듣고 있습니다. 항상 감사드립니다.Purpose다름이 아니라, UserControllerTest 관련 질문이 있어서 이렇게 문의 드립니다.링크: https://github.com/codingspecialist/junit-bank-class/blob/main/src/test/java/shop/mtcoding/bank/web/UserControllerTest.java Situation강의에서 나온 대로 `join_success_test()`와 `join_fail_test()` 따로 실행시키면 정상적으로 테스트가 통과합니다.다만 궁금한 점이 둘이 동시에 테스트를 진행하면(UserControllerTest 클래스 단위로 테스트를 실행하면) `join_success_test()` 테스트에서 실패가 뜨는데요.Approach제 생각에는 테스트 진행 시 `join_fail_test()`이 먼저 실행된다면, repository에 "ssar"이 먼저 등록되고,@BeforeEach public void setUp() { dataSetting(); } private void dataSetting() { userRepository.save(newUser("ssar", "쌀")); }그 다음 `join_success_test()`가 진행될 때 `dataSetting()` 에서 "Unique index or primary key violation"이 발생하는 게 아닐까 생각이 드는데요. 제가 유추한 것이 맞을까요?Question맞다면, 하나 더 궁금한 점이 매번 @BeforeEach로 돌면서userRepository.save(newUser("ssar", "쌀"));가 등록이 된다면, 하나의 repository에 계속해서 중복된 값이 저장되기 때문에 오류가 생기진 않나요?질문이 길어졌습니다.매번 친절하게 답변해주셔서 감사합니다.
-
미해결Practical Testing: 실용적인 테스트 가이드
SpringSecurity 사용 시 Controller 테스트
안녕하세요 좋은 강의를 제공해주셔서 너무 감사합니다. 평소 테스트에 대해 고민하던 많은 부분이 해결되었습다. 그러나 아직 해결하지 못 한 부분이 있습니다.전 개인 프로젝트에 Spring Security 를 이용해 인증 및 인가를 구현하였습니다. 또한, 컨트롤러에 @AuthenticationPrincipal 을 이용해 인증 객체를 가져와 로그인한 회원의 정보를 사용하고 있습니다.강사님의 경우 @WebMvcTest 를 이용해 컨트롤러만 띄워 최소한의 파라미터만 검증하였습니다. 저 역시 처음엔 @WebMvcTest 를 이용해 최소한의 비용으로 컨트롤러를 테스트해보려 했으나 테스트 수행 시 Security 관련 빈이 없어 잦은 오류가 발생하였습니다.이 경우 @WebMvcTest 를 그대로 사용하며 TestSupport 와 같은 클래스에 시큐리티 관련 빈들을 모두 목킹하고 @AuthenticationPrincipal 으로 가져오는 인증객체 또한 목킹하는 것이 좋은 테스트일지 @SpringBootTest 를 사용한 다음 인증객체를 주입하는 것이 좋은 테스트인지 잘 판단이 안됩니다. (@AuthenticationPrincipal 의 경우 컨트롤러 메서드의 파라미터로 들어가는데 이것 역시 목킹이 가능한지도 잘 감이 안잡힙니다.)마지막으로 Spring Security 를 구성하는 필터 혹은 인터셉터나 kafka, websocket 같은 비동기 통신의 경우 실무에서 어떻게 테스트를 수행하는지 궁금합니다!긴 질문 읽어주셔서 감사합니다
-
해결됨실무에 바로 적용하는 프런트엔드 테스트 - 1부. 테스트 기초: 단위・통합 테스트
4.3. 강의와 깃헙 소스코드가 다른 부분
안녕하세요. 강의 잘 듣고 있습니다.다름이 아니라 강의와 깃헙 소스코드가 달라서 문의드려요. mocks/zustand.js의 코드인데요.const { create: actualCreate } = await vi.importActual('zustand'); import { act } from '@testing-library/react'; // 앱에 선언된 모든 스토어에 대해 재설정 함수를 저장 const storeResetFns = new Set(); // 스토어를 생성할 때 초기 상태를 가져와 리셋 함수를 생성하고 set에 추가합니다. export const create = createState => { const store = actualCreate(createState); const initialState = store.getState(); storeResetFns.add(() => store.setState(initialState, true)); return store; }; // 테스트가 구동되기 전 모든 스토어를 리셋합니다. beforeEach(() => { // 👈 이 부분 act(() => storeResetFns.forEach(resetFn => resetFn())); });깃헙 소스코드는 위와 같이 beforeEach를 사용하지만 강의에서는 afterEach로 설명해주시고 있습니다.주석도 마찬가지로 다릅니다.무엇이 맞는 걸까요?