묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨Practical Testing: 실용적인 테스트 가이드
안녕하세요. 객체의 책임 분리와 관련해서 질문이 있습니다.
안녕하세요. "private 메서드 테스트는 어떻게 하나요?" 강의를 들으며 객체의 책임 분리에 대하여 질문드릴 것이 있습니다.객체의 책임 분리를 위해 별도의 Class를 만들고 객체를 생성해서 해당 객체에게 특정 책임을 부여하려면 결국에 별도의 Class를 만들어야 한다는 것이 전제될텐데요.현재 제가 일하는 곳에서 대표님이 Class가 많이 늘어나게 되면 유지보수가 어렵게 되고 코드가 지저분해질 수 있다고 하신 적이 있습니다. 전 객체지향 관점에서 한 객체가 모든 걸 다 하고 한 메서드가 너무 많은 행위를 하는 것이 좋지 않다고 생각하는데 우빈님은 혹시 제가 들은 대표님의 말씀에 대해 어떻게 생각하시는지 궁금합니다.
-
미해결Java/Spring 주니어 개발자를 위한 오답노트
Controller / application Service / Domain 의 역할 구분
안녕하세요 강의 잘 듣고 있습니다.헥사고날 아키텍쳐 부분 강의를 듣고, 궁금한 부분이 새겨서 질문 남깁니다!Application Service(이하 서비스) 에서 도메인부분을 분리 하여 객체의 상태 변화에 대한 부분을 처리하도록 하고, 서비스에선 Repository와 소통해서 필요한 객체나 컨트롤러에서 정보(예를 들어 수정 정보 등등) 등등을 얻어서 도메인 부분에 위임한다고 이해했습니다. 그렇게 도메인 영역을 분리하면 테스트에 용이하다는 것은 이해했습니다. 그런데 실제로 토이프로젝트에 적용해보려고 코드를 수정하는 중에 예를 들어 게시글을 수정하는 과정이라면 컨트롤러에서 처음 요청을 받을 때 postId, updateRequest를 받아서 서비스에 업데이트를 요청하고, 다시 서비스에선 아이디를 통해 Post를 찾고, PostDomainService(가칭)에 Post와서 updateRequest를 넘겨 수정한다면 거의 같은 내용의 파라미터를 굳이 2 계층을 건너 불필요한 위임이 반복 된다고 생각했습니다. 궁금한 것은 2가지 입니다.이런 경우엔 PostDomainService 클래스를 만들기보단 Post 객체 자체에서 업데이트를 처리하는 것이 맞을까요? - (1번 코드)도메인과 도메인 서비스의 차이는 객체의 상태(도메인)와 객체의 행동(도메인 서비스) 일까요? 엔티티와 도메인의 구분이 잘 이해가 되지 않습니다. //== 업데이트 로직 ==// public void updateInfo(PostUpdateReqDto updatePost) { this.title = updatePost.getTitle(); this.content = updatePost.getContent(); } // 기존 서비스에서의 로직 @Transactional public PostUpdateResDto updatePost(final Long postId, final PostUpdateReqDto postUpdateReqDto) { Post findPost = postRepository.findWithMemberByPostId(postId); Post updatedPost = postDomainService.updatePost(findPost, postUpdateReqDto); // 위 과정에 생기면 사라지는 메서드 // findPost.updateInfo(postUpdateReqDto); checkForbiddenWord(findPost); return new PostUpdateResDto(findPost); }
-
미해결따라하며 배우는 리액트 A-Z[19버전 반영]
useParams를 이용한 영화 상세 페이지 구현하기
useParams를 이용한 영화 상세 페이지 구현하기에서 가져올 useParams에 파라미터 값이 movieId인 것을 어떻게 확인할 수 있을까요 ?
-
해결됨Practical Testing: 실용적인 테스트 가이드
lesson5-5 Order Entity의 registeredDateTime 컬럼
학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요!먼저 유사한 질문이 있었는지 검색해 보세요.서로 예의를 지키며 존중하는 문화를 만들어가요.질문Order Entity가 상속 받는 BaseEntity에 createdDateTime 컬럼이 있음에도 registerdDateTime 컬럼을 추가하는 이유는 무엇인가요? 외부결제API에서 제공하는 결제일시를 저장하기 위함인가요?
-
해결됨Practical Testing: 실용적인 테스트 가이드
안녕하세요 선생님 질문 있습니다 !
이제 막 java, spring, mysql , 프론트 부분 기초적인 부분 공부를 끝마친 학생입니다.항상 테스트 코드의 중요성을 많은 커뮤니티에서 봐오고 강조하는 분들이 많아서언젠간 배워야겠다 싶은 찰나에 수강 결제를 미리 하게 되었습니다.혹시 선생님 수업을 듣기 전, 미리 좀 더 배워둬야 하거나알아둬야 하는 부분이 있을까요 ?
-
미해결스프링부트 JUnit 테스트 - 시큐리티를 활용한 Bank 애플리케이션
로그인 인증 실패 시 예외처리하는 주체는 어느 것인가요?
기존에는 SecurityConfig 클래스의SecurityFilterChain에서 아래의 코드가로그인 실패 시 응답을 처리하는 주체였습니다. http.exceptionHandling() // 인증 예외 설정 .authenticationEntryPoint((request, response, authenticationException)->{ // 예외 가로채기\ CustomResponseUtil.fail(response, "로그인을 진행해주세요", HttpStatus.UNAUTHORIZED); });그러다 JwtAuthenticationFilter를 만들면서attemptAuthentication() 매서드가 실패 시 아래의unsuccessfulAuthentication()가 실행되게끔 했구요.@Override protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException { CustomResponseUtil.fail(response, "로그인 실패", HttpStatus.UNAUTHORIZED); } 그래서 헷갈려서 실험해보니 기존의 SecurityFilterChain의 것은 주석처리해도 아무런상관이 없고, unsuccessfulAuthentication()가 동작하더라구요.이 두 코드의 차이는 정확히 어떤 것일까요?
-
해결됨Practical Testing: 실용적인 테스트 가이드
빌더 사용에 대해 질문드립니다!
안녕하세요 선생님. 빌더를 사용하시는 것을 보고 흥미가 동해 질문남깁니다!선생님께서는 예제의 경우 대부분 생성자를 private으로 막아두고 빌더를 통해서만 객체를 생성하시는 것 같습니다.저는 필드 개수가 많아도 public 생성자로 열어두는 편인데, 그 이유는어떤 인자를 전달해야할지 인텔리제이의 힌트로 알아채기도 편하고필드가 null 일 수도 있는 경우 객체를 생성할 때 명시적으로 null 이 보이는게 낫다 라고 생각해서입니다. null을 명시적으로 인자로 전달하는 것이 불편하다면 텔레스코핑을 통해 생성자를 조금 더 만들어두기도 합니다 :)물론 빌더 패턴을 사용하면 이런 코드들이 전부(?) 사라지기는 하지만, 이 외에 빌더로 객체 생성을 강제하는 것에 대한 장점이 있는지 궁금합니다! 또, 선생님만의 빌더랑 생성자 선택 기준이 따로 있을까요? 마지막으로 실무에서도 자주 사용하시는지 궁금합니다. 좋은 강의 감사드립니다 :)
-
미해결따라하며 배우는 리액트 A-Z[19버전 반영]
async await
안녕하세요. banner.js에서 질문이 있습니다이 부분에서 왜 async await를 사용하셨는지 궁금합니다!const fetchData = async () => { // 현재 상영중인 영화 정보를 가져오기(여러 영화) const request = await axios.get(requests.fetchNowPlaying); // 여러 영화 중 영화 하나의 ID를 가져오기 const movieId = request.data.results[ Math.floor(Math.random() * request.data.results.length) ].id; // 특정 영화의 더 상세한 정보를 가져오기(비디오 정보도 포함) const { data : movieDetail } = await axios.get(`movie/${movieId}`, { params: {append_to_response: "videos"}, }); setMovie(movieDetail); }
-
해결됨Java/Spring 주니어 개발자를 위한 오답노트
테스트 하기 쉬운 코드에서 테스트의 범위?
영상에서 종종 "테스트 하기 좋은 코드는 잘 설계된 코드일 것이다." 라는 말을 해주셨습니다. 어떤 테스트를 기준으로 테스트 하기 좋은 코드가 잘 설계된 코드일까요?- 예를 들어 단위 테스트, 통합 테스트, 인수 테스트가 존재한다 하면, 세가지 테스트 중 어떤 테스트를 테스트하기 편한 코드를 기준으로 잡는게 좋을까요?
-
해결됨Java/Spring 주니어 개발자를 위한 오답노트
스프링에서 서비스 레이어(Apllication Layer) 테스트에 대한 질문입니다.
제 개인 프로젝트를 진행하면서, 서비스 레이어에서는 단순히, 도메인 레이어에 존재하는 다른 객체들을 호출해서 비즈니스 로직을 처리하는 책임만을 담당하다보니, 서비스 레이어에 존재하는 객체를 테스트하는 코드를 작성하게 되면 대부분 테스트할 내용이, 메소드의 실행순서를 올바르게 실행해줬는가? 와 같은 부분만 테스트할게 없었는데 이 부분이 제가 잘못 설계한 부분이 아닌 오히려, 객체간의 책임을 잘 나누고 서비스 레이어의 책임에 맞게 코드를 작성한것 같다는 확신을 강의를 보고나서 알수 있었습니다 좋은 강의 감사합니다😊
-
해결됨스프링부트 JUnit 테스트 - 시큐리티를 활용한 Bank 애플리케이션
(해결완료) MockMvc를 이용한 테스트가 안됩니다.
※※※※※ 해결완료 ※※※※※mvc.perform()의 get이나 post 같은 매서드 타입을스태틱임포트 해야하는데이 때 선택지가 3개 있습니다.이 중 MockMvcRequestBuilders의 post()를임포트 하니까 해결이 됐습니다.RequestBuilder로 캐스팅을 해주지 않아도 되구요그리고, 이래저래 해보면서 MockMvc 말고도MockMvcBuilder 객체를 이용해서 build().perform()으로 시작해 똑같이 코드를 작성하면 테스트가 정상적으로 실행됩니다!※※※※※ 해결완료 ※※※※※SecurityConfig 테스트 강의에도 질문을 드렸는데..답이 없길래 그냥 넘어갔는데 여기서도 쓰여다시 질문드립니다.MockMvc를 이용해서 테스트를 진행할 때,@Test @DisplayName("회원가입 테스트") void join_test() throws Exception { // given JoinRequestDto joinRequestDto = JoinRequestDto.builder() .username("minsu") .password("1234") .email("minsu@gmail.com") .fullname("김민수") .build(); String requestBody = objectMapper.writeValueAsString(joinRequestDto); System.out.println("requestBody = " + requestBody); // when ResultActions resultActions = mvc.perform((RequestBuilder) post("/api/join").content(requestBody).contentType(MediaType.APPLICATION_JSON)); // then }위 부분에서 문제가 생기는 부분은 아래 코드인데요// when ResultActions resultActions = mvc.perform((RequestBuilder) post("/api/join").content(requestBody).contentType(MediaType.APPLICATION_JSON));먼저 content를 설정할 수 있는 api?가 없고요.해당 구문을 RequestBuilder로 캐스팅해야빨간줄이 사라집니다. 그러니까 perform()이 파라미터로 RequestBuilder를 받게 돼있습니다.gradle은 아래와 같습니다.plugins { id 'java' id 'org.springframework.boot' version '2.7.12' id 'io.spring.dependency-management' version '1.0.15.RELEASE' } group = 'io.com' version = '0.0.1-SNAPSHOT' sourceCompatibility = '11' dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'com.auth0:java-jwt:4.2.1' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' runtimeOnly 'com.h2database:h2' runtimeOnly 'com.mysql:mysql-connector-j' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.security:spring-security-test' } 그리고 테스트쪽 라이브러리는 아래와 같습니다.Gradle: org.junit.jupiter:junit-jupiter:5.8.2Gradle: org.junit.jupiter:junit-jupiter-api:5.8.2Gradle: org.junit.jupiter:junit-jupiter-engine:5.8.2Gradle: org.junit.jupiter:junit-jupiter-params:5.8.2Gradle: org.junit.platform:junit-platform-commons:1.8.2Gradle: org.junit.platform:junit-platform-engine:1.8.2Gradle: org.mockito:mockito-core:4.5.1Gradle: org.mockito:mockito-junit-jupiter:4.5.1
-
해결됨Practical Testing: 실용적인 테스트 가이드
통합, 인수 테스트 사전 데이터 세팅 질문
안녕하세요 강의 잘 보고 있습니다.테스트에 대해 파편화 된 지식을 학습자들이 원하는 내용으로 잘 만들어 낸 좋은 강의라고 생각합니다. 현재 저희 팀음 통합 테스트 및 인수 테스트를 할 때 미리 쿼리문을 작성해두고 이를 @SqlGroup과 @Sql을 활용하여 데이터를 삽입해주고 있습니다.이 경우 강의 내에서 말씀하신 것 처럼 스키마 변경이 생길때마다 모든 쿼리를 찾아 수정해야하는 번거로움이 있습니다. 하지만 매 케이스마다 세팅을 하기에는 연관된 5개~10개의 테이블에 대한 데이터 수십개를 매번 세팅해줘야 하는 것이 어렵게 느껴집니다.이때 repository를 계층을 넘어서까지 임포트 해서 사전 데이터 삽입을 해줘야 하는가 궁금하구요.또한 모든 객체에 Builder를 개방하면 그나마 할만하겠지만 아닌 경우 객체가 제공하는 제한적으로만 생성이 가능할텐데, 리플렉션이라도 써야하는건지 너무 걸리는 경우가 많습니다. 다소 두서 없고 여러 질문을 한번에 했지만 제가 어떤 어려움을 겪는지는 전달 되었으리라 생각합니다.
-
미해결Java/Spring 주니어 개발자를 위한 오답노트
Repository 대신 Reader / Writer 사용 질문있습니다!!
안녕하세요.회사내에서 Reader, Writer 개념을 도입하여 사용하고 있습니다. 흐름은 아래와 같습니다controller -> service -> reader or writer -> repository제가 궁금한것은 JPA를 사용하고 있어 단건데이터 수정시 더티체킹을 하고 있는데요.writer내에서 더티체킹을 위한 엔티티를 조회하는거 조차 하면 안되는지 궁금합니다!안된다면 reader에서 엔티티를 조회하고 서비스로 반환한 다음 해당 엔티티를 writer로 넘겨줘야 하는지요..!!아 그리고 해당 강의가 지식공유자 답변 미제공 강의더라구요 ㅠㅠ 답변이 의무는 아니시지만 선생님의 지구 내핵 같은 깊은 배려심으로 답변을 해주시는거신지요.. 한줄기 빛 같은 강의(강의보다 시력 0.2 감소됨) 감사드립니다.
-
미해결Java/Spring 주니어 개발자를 위한 오답노트
ProductService부분에서 리팩토링 언급 질문
안녕하세요. 강의 너무 잘 듣고 있습니다.섹션2의 '스프링에서 OOP와 안티패턴 : Transactiojn script' 회차를 듣던 중 10분 42초 부분에서 ProductService 코드를 리팩토링하고 싶다고 말씀해주셨는데 어떤 부분에서 리팩토링 하고 싶으신건지 궁금합니다!! 제 부족한 지식으론 딱히 건드릴게 보이질 않아서요 ㅠㅠ※ 3년차 개발자이지만 회사 내 사수가 없어 좌절하고 있던 시기에 우근님의 강의를 듣는 순간 가뭄의 단비와 같으며 세상에서 가장 달콤한 술을 먹은 것 마냥 취하게 해주셔서 감사합니다..
-
해결됨스프링부트 JUnit 테스트 - 시큐리티를 활용한 Bank 애플리케이션
MockMvc.perform(get("/api/s/hello")); 구문 에러납니다
안녕하세요 선생님 유튜브에 이어 인프런에서도 잘 보고 있습니다.|다름이 아니라 SecurityConfigTest에서이번 강의의 첫 테스트 코드를 작성하고 있는데, ResultActions resultActions = mvc.perform(get("/api/s/hello"));코드에서 get()이라는 매서드에서 빨간 줄이 뜹니다. 그러니까 자동완성으로도 get()이라는 매서드는 뜨지 않고, More Action에도 적절한 답이 없습니다. 보면 매서드를 스태틱 임포트한 것 같은데.. 혹시 제가 이상한건가요?
-
미해결Java/Spring 테스트를 추가하고 싶은 개발자들의 오답노트
의존성을 분리하는 건 캡슐화를 깼다고 볼 수 없을까요?
07:05 부근에서 메서드 내에 내부 알고리즘을 확인한 시점에서 캡슐화가 깨졌다는 언급을 해주셨습니다.개인적으로 생각했을 때는 의존성을 분리했을 때 또한 로직이 외부(인자)로 노출되므로 이것도 캡슐화가 깨졌다고 볼 수 있는 것 아닐까요?
-
해결됨Practical Testing: 실용적인 테스트 가이드
setup 해야하는 데이터가 대용량인 경우 테스팅 가이드
안녕하세요. 우빈님양질의 강의 제공해주셔서 감사의 말씀드립니다. 강의를 듣던 도중 실무에서는 어떻게 해결을 할까? 🤔라는 궁금증이 생겨 질문 드립니다. 만약에 테스트 코드 작성시에 setup해야 할 데이터가 대용량이라면실무에서는 주로 어떤 방식으로 테스트 코드를 작성하여 해결하나요? 감사합니다.
-
미해결Practical Testing: 실용적인 테스트 가이드
테스트 오류
org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : example.cafekiosk.spring.domain.orderproduct.OrderProduct.product -> example.cafekiosk.spring.domain.product.Product; nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : example.cafekiosk.spring.domain.orderproduct.OrderProduct.product -> example.cafekiosk.spring.domain.product.Product 스프링부트 2.7.12 인데 오류가 납니다.. 강사님 코드를 보니 OrderProduct Entity 쪽엔 cascade 가 설정이 안되어 있는데 설정을 하니 오류가 없어졌습니다..!
-
미해결따라하며 배우는 리액트 테스트 [2023.11 업데이트]
toHaveTextContent 에러
안녕하세요.'context wrapper 추가로 에러 제거하기' 강의에서 발생한 에러가 해결되지 않아 질문 드립니다.https://www.inflearn.com/questions/736423/tohavetextcontent-%EC%97%90%EC%84%9C-%EC%97%90%EB%9F%AC%EA%B0%80-%EC%9E%90%EA%BE%B8-%EB%82%98%EB%8A%94%EB%8D%B0-%EC%95%84%EB%AC%B4%EB%A6%AC-%EC%B0%BE%EC%95%84%EB%8F%84-%EC%9E%98-%EB%AA%A8%EB%A5%B4%EA%B2%A0%EC%8A%B5%EB%8B%88%EB%8B%A4이 글과 동일한 에러가 계속 발생하는데, 이 질문자분이 답글로 남겨주신 코드로 수정해보아도 해결이 되지 않습니다. 어디서 문제가 발생한 건지 강의를 다시 보고 또 봐도 찾기가 어려워 깃허브 주소 남깁니다. 감사합니다.● update product's total when products change expect(element).toHaveTextContent() Expected element to have text content: 1000 Received: 총 가격: 0 16 | userEvent.clear(americaInput); 17 | userEvent.type(americaInput, "1"); > 18 | expect(productsTotal).toHaveTextContent("1000"); | ^ 19 | }); 20 | at Object.<anonymous> (src/pages/OrderPage/test/calculate.test.js:18:25) https://github.com/daeunleeeee/react-shop-test
-
해결됨부트캠프에서 알려주지 않는 것들 (리액트) 1편
TDD - Green, Red, Refactor
안녕하세요. TDD의 Green, Red, Refactor 파트(9:40)에서리팩터링을 진행하시면서 onPageNumberClick 함수를 useCallback으로 감싸서 렌더링이 다시 될때 이 함수가 두번 생성되지 않도록 한다고 하셨는데이 부분이 잘 이해가 가지 않아서요. 설명해주신걸로 유추해보면 useCallback으로 감싸면 함수가 한번만 생성되는 것 같은데 useCallback을 사용했을때와 사용하지 않았을 때 차이에 대해서 조금 더 설명해주실 수 있을까요?