묻고 답해요
160만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결실전! 스프링부트 상품-주문 API 개발로 알아보는 TDD
패키지 구조에 대해서 궁금합니다!
안녕하세요 좋은 강의를 무료로 올려주셔서 정말 잘 보고있습니다.보여주신 패키지 구조가 헥사고날 패키지 구조에 기반 하셨다고 다른 글에서 말씀을 해주셨던 것을 봤습니다. 그럼 controller 를 넣게 된다면 port 에 in 폴더를 넣고 다시 나누는 작업을 하시나요? 그리고 실무에서도 Controller 없이 Service 에 바로 GetMapping 을 넣어도 괜찮을까요?감사합니다!
-
미해결Practical Testing: 실용적인 테스트 가이드
Builder 패턴은 언제 사용하고 언제 사용하지 않는게 좋은 건가요
안녕하세요!! 강의 중 ApiResponse라는 제네릭 클래스를 만들 때에는 Builder를 사용하지 않으셨는데, 제네릭 클래스여서 사용하지 않은 건가요??그리고 혹시 Builder패턴을 사용을 하지 않았으면 하는 부분들이 있을까요?항상 친절하게 답해주셔서 감사합니다!!
-
해결됨Practical Testing: 실용적인 테스트 가이드
현업에서 TDD를 사용하시나요?
학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요!먼저 유사한 질문이 있었는지 검색해 보세요.서로 예의를 지키며 존중하는 문화를 만들어가요.강사님은 현업에서 TDD를 사용해서 개발하시는지 궁금합니다!
-
미해결Java/Spring 테스트를 추가하고 싶은 개발자들의 오답노트
서비스 레이어 끼리의 의존
안녕하세요. 강의가 너무 재미있어 시간가는 줄 모르고 1편, 2편 강의 완강 하고있습니다. 2편, 테스트 관련해서 실습을 하던 중 고민이 생겨서 질문을 올리게 되었습니다.자바/스프링으로 코딩을 하다가 A Service와 B Service가 의존관계를 갖게 된다면 어떻게 해야할지가 너무 고민이여서요.만약 2편에 있던 도메인 User, Post에 User의 프로필 이미지 업로드기능, Post의 이미지 업로드기능이 있다고 할 때, File의 정보를 저장할 수 있는 File 도메인이 있어야 한다고 생각합니다.File에 대응하는 FileService를 만든다고 가정 하였을 때 DB 등에 파일의 정보 데이터를 저장하는 FileRepository, 파일을 업로드 하는 FileUploader를 만든 후 의존관계가 이런형태로 구성 되어야 한다고 생각합니다. FileService에 saveAndUpload() 라는 메서드가 있고 이 메서드를 공통으로 사용하고 싶을 때 UserServiceFacade, PostServiceFacade와 같은 형태로 퍼사드를 써야할지, UserService, PostService 에 각각 업로드 메서드를 구현을 해야할지 고민이 됩니다. Facade와 같은 형태로 코드를 작성하게 된다면 User, Post가 아닌 파일이 필요로 하는 도메인이 추가 될 때 마다 Facade를 작성해줘야하는 번거로움이 있을 것 같고,Service 각각에 업로드 메서드를 구현하자니 반복적인 코드가 들어가는 것이 마음에 조금 걸려서 질문드립니다.
-
해결됨스프링부트 JUnit 테스트 - 시큐리티를 활용한 Bank 애플리케이션
vs code setting에서 gradle
안녕하세요 강사님!질문 올립니다.vs code 세팅 중 3번째 gradle 설치에서 gradle for java를 설치한 뒤에 아래와 같은 문구가 뜹니다.구글링 해보니 이전에 했던 스프링 프로젝트의 gradle 버전과 겹쳐서 발생하는 에러라고 하더라고요.C:\Users\사용자\.gradle\caches에 들어가서 캐시를 전부 삭제했습니다.그런데 위 그림이 계속 떠요.다른 extensions이나 이전 스프링 프로젝트 데이터를 전부 지우고, 구글에 나온 방법은 거의 다 해봤는데 며칠동안 해결을 못했습니다. cache.propertiesgradle.version=8.2.1 build.gradleplugins { id 'java' id 'org.springframework.boot' version '2.7.14' id 'io.spring.dependency-management' version '1.0.15.RELEASE' } group = 'shop.metacoding' version = '0.0.1-SNAPSHOT' java { sourceCompatibility = '11' } configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' } tasks.named('test') { useJUnitPlatform() } gradle-wrapper.propertiesdistributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists 살려주십셔
-
미해결따라하며 배우는 리액트 테스트 [2023.11 업데이트]
Test Fail이 발생합니다 ㅠㅠ
현재 섹션5까지 수강 완료한 상태인데 계속 Fail이 발생합니다 ㅠㅠ처음엔 됐었는데 갑자기 안되더라구영 ㅠㅠ 검색을 해봐도 뭐가 문제인지 파악하기 힘들어서 질문 드립니다!어떻게 해결하면 좋을까요?
-
미해결Java/Spring 테스트를 추가하고 싶은 개발자들의 오답노트
답변해줘요.....................
답변해줘요.....................
-
미해결Java/Spring 테스트를 추가하고 싶은 개발자들의 오답노트
님들 아무리봐도 PostCreate PostUpdate는 서비스쪽에 있어야하지 않을까요?
서비스에서 사용하는 모델인 거 같은데제 생각입니다.다른 의견 적어주시면 감사합니다.
-
미해결Practical Testing: 실용적인 테스트 가이드
TEST 코드 내에서 발생하는 쿼리의 바인딩 되는 부분을 볼 수 있나요?
안녕하세요. 강의를 듣다가 테스트를 하며 JPA에서 제공하는 쿼리가 제가 원하는 쿼리가 맞는지 확인함과 더불어 실제 들어가는 값이 제대로 들어가는지 알고 싶을 때가 존재하는데 이때 로그에서 확인할 수 있는 방법이 있을까요?
-
미해결스프링부트 JUnit 테스트 - 시큐리티를 활용한 Bank 애플리케이션
스프링 시큐리티 관해서 좀더 찾아봤는데 이과정들이 강의에선 언급이 안되었지만
HTTP요청이 들어오면 Servlet 컨테이너에서 요청을 받는다.Servlet 컨테이너 내의 필터들이 동작하는 중간에 DelegatingFilterProxy Filter가 요청을 받으면 springSecurityFilterChain 이름으로 생성된 빈을 AnnotationConfigServletWebServerApplicationContext 객체에서 찾는다.이 찾은 Filter Bean이 바로 FilterChainProxy다.그 후에 FilterChainProxy Bean에 요청을 전달한다. 이제 FilterChainProxy에서 필터들을 이용하여 보안처리를 진행한 후 최종적으로 SpringMVC의 DeispatcherServlet에 전달하여 요청에 대한 Servlet 처리를 하게 된다. ==유저가 서버에 요청을 보낸다.요청이 DelegatingFilterProxy 필터를 만나고 FilterChainProxy에 위임되어 등록되어 있는 SecurityFilterChain들의 조건과 매칭한다. 이번 예제에서는 어떤 요청이든 인증을 받도록 했다.매칭되는 SecurityFilterChain이 있는 경우 해당 필터 체인으로 흐름이 이어진다.필터 체인을 돌면서 여러 처리를 하고 AuthenticationFilter를 만나 인증을 수행한다.AuthenticationFilter에서는 AuthenticationToken을 만들고 AuthenticationManager에게 인증 여부를 요청한다.AuthenticationManager는 내부의 AuthenticationProvider들 중 처리할 수 있는 AuthenticationProvider에게 인증 여부를 요청한다.AuthenticationProvider는 UserDetailsService를 통하여 유저 정보를 가져온다.위에 과정들이 이루어지고 있긴 한거죠? 강의에선 언급이 안되었지만,,, 깊게 파고들수록 어렵네요
-
해결됨Practical Testing: 실용적인 테스트 가이드
시간대에 따라서 변화하는 로직 테스트 하는 가이드
안녕하세요. 우빈님 시간대에 따라 다른 결과를 주는 로직을 테스트 하는 과정에서 고민이 있어 질문을 드립니다. 우빈님이 강의에서도 언급하셨지만, 시간과 같이 관측할 때마다 달라지는 영역은 외부로 분리하면 테스트하기 쉬워진다고 말씀하셨습니다.!하지만, 현재 서비스 레이어 까지만 분리가 가능하고 컨트롤러에서 LocalDateTime을 파라미터로 받지 못하는 상황입니다. 그래서 컨트롤러를 테스트할 때 어떻게 해야할까 고민을 좀 해봤는데요. 저의 결론은 TimeProvider라는 클래스를 하나 만들어서컨트롤러를 테스트할 때는 이를 mocking하는 방식으로 테스트 코드를 작성했습니다. TimeProvider/** * 시간을 고정하여 테스트하기 위해 사용 */ @Component public class TimeProvider { public LocalDateTime getCurrentLocalDateTime() { return LocalDateTime.now(); } } ControllerGET을 사용하고 싶은데, 외부와 연동해야해서 POST를 사용할 수 밖에 없습니다. ㅠㅠ/** * 인기 메뉴 조회 * 현재 시간대의 식사종류와 일치하는 가장 조회수가 많은 금일 식사 메뉴 조회 */ @PostMapping("/menu/top1-view") public ResponseEntity<SkillResponse> getTop1RestaurantMenuByView(@RequestBody SkillPayload payload, @PageableDefault(size = 1) Pageable pageable) { log.info("request={}", payload); Page<RestaurantMenuResponse> top1RestaurantMenuByView = restaurantService.findTop1RestaurantMenuByView(pageable, timeProvider.getCurrentLocalDateTime()); RestaurantsMenuResponse response = new RestaurantsMenuResponse(top1RestaurantMenuByView.getContent()); return new ResponseEntity<>(response.toSkillResponseUseTextCard(apiVersion), HttpStatus.OK); } Test Code@Test @DisplayName("추천수 가장 많은 메뉴를 1개 조회한다.") void getTop1UosRestaurantMenuByView() throws Exception { // given // 현재 시간을 고정할 시간 생성 LocalDateTime fixedDateTime = LocalDateTime.of(2023, 8, 16, 10, 59, 59); when(timeProvider.getCurrentLocalDateTime()).thenReturn(fixedDateTime); String date = CrawlingUtils.toDateString(fixedDateTime); restaurant restaurant1 = createUosRestaurant(date, STUDENT_HALL, MealType.BREAKFAST, "라면", 0, 0); restaurant restaurant2 = createUosRestaurant(date, MAIN_BUILDING, MealType.BREAKFAST, "김밥", 1, 0); restaurant restaurant3 = createUosRestaurant(date, WESTERN_RESTAURANT, MealType.BREAKFAST, "돈까스", 2, 0); restaurant restaurant4 = createUosRestaurant(date, MUSEUM_OF_NATURAL_SCIENCE, MealType.BREAKFAST, "제육", 2, 1); restaurantRepository.saveAll(List.of(restaurant1, restaurant2, restaurant3, restaurant4)); SkillPayload skillPayload = createSkillPayload(RestaurantName.STUDENT_HALL.name(), MealType.BREAKFAST.name()); // when // then mockMvc.perform(post("/api/v1/text-card/restaurant/menu/top1-view") .contentType(MediaType.APPLICATION_JSON) .content(om.writeValueAsBytes(skillPayload)) .content(om.writeValueAsString(PageRequest.of(0, 1)))) .andDo(print()) .andExpect(status().isOk()) .andExpect(jsonPath("$.version").value(SkillResponse.apiVersion)) .andExpect(jsonPath("$.template").isNotEmpty()) .andExpect(jsonPath("$.template.outputs").isArray()) .andExpect(jsonPath("$.template.outputs[0].textCard").isNotEmpty()) .andExpect(jsonPath("$.template.outputs[0].textCard.text").isString()); } 이런식으로 작성하는 것이 최선일까요?LocalDateTime fixedDateTime = LocalDateTime.of(2023, 8, 16, 10, 59, 59); when(timeProvider.getCurrentLocalDateTime()).thenReturn(fixedDateTime);TimeProvider 클래스를 만들어서 mocking 하는 방법이 최선일까요?혹시 더 좋은 방법을 말씀주시면 감사하겠습니다.! 좋은 강의 만들어 주셔서 감사합니다.^^
-
해결됨Java/Spring 주니어 개발자를 위한 오답노트
강의와 크게 상관은 없지만 공부의 방향성에 대해서 질문합니다.
저는 올해 4월에 입사해서 이제 막 4개월차 주니어 개발자 입니다.퇴근 후에 공부를 하려고 하다가 매번 생각이 많아지는 주제인데요.저의 주요 업무는 전자정부프레임워크 기반의 jsp사이트를 ui유지보수하는 업무입니다.더 좋은 회사를 합격하지 못해서 아쉽긴하지만 그래도 신입받아주는 회사들이 많이 없어서 일단은 기분좋게 다니려고 하고 있습니다. 그런데 회사 업무를 하는 데 앞서서 공부를 하려고 하다보면 자꾸만 그런생각이 들더라구요. jsp/mybatis 를 이렇게 까지 공부해야하나? 전자정부프레임워크 어차피 다른 서비스 기업으로 이직하게 되면 안쓸텐데 굳이 이렇게 공부해야할까 하고요.그래서 회사기술스택에 맞춰서 해야할지 지금듣고 있는 김영한님 스프링강의를 들으면서 개인 포트폴리오를 보강하는 것이 나은지 둘다 하면 되지않냐고도 할수 있지만 그게 정말 맞는 방법인지 하는 의구심이 듭니다.최우선적으로 뭘 중점적으로 해야하는지 우선순위를 명확하게 알고싶습니다!!
-
해결됨Practical Testing: 실용적인 테스트 가이드
예외 처리에 대한 rest doc 작성하기
안녕하세요!강사님 덕분에 테스트에 많은 관심이 생겨 개인 프로젝트에도 적용을 해보고 있습니다! Rest doc 작성 중 궁금한 점이 생겨 질문드립니다.API의 정상 응답이 아닌 예외 발생 시의 응답도 Rest doc으로 작성하고자 합니다.예를 들어 인증, 인가 관련하여 예외가 발생하는 경우가 있을 때 다음과 같이 생각했습니다.예외 케이스 별로 에러 코드를 상세하게 나누어 세밀한 응답을 전달하기 (ex. 아이디가 틀렸을 때 - 401A, 비밀번호가 틀렸을 때 - 401B, 아이디가 존재하지 않을 때 - 401C 등등..)공통 예외코드로 처리하기 (ex. 인증 실패 시 어떤 경우라도 401 코드 반환)위의 2가지 경우에 어떤 식으로 rest doc을 작성하는 것이 좋을까요? 1번 케이스의 경우는 특정 API 문서마다 함께 적는 것이 좋을 것 같긴 한데 2번 케이스의 경우는 프로젝트 전반적인 공통 예외처리라 별도의 문서 항목으로 1개만 작성하는 게 좋을 지 고민이 됩니다. 혹시 현업에서는 예외 발생 시 응답에 대한 문서도 작성하시는 지 궁금하고 1번, 2번 케이스에 대하여 어떻게 rest doc을 작성하는 것이 다른 인원과 소통하기 편할지 의견 부탁드리겠습니다! 감사합니다.
-
미해결Java/Spring 주니어 개발자를 위한 오답노트
진짜 객체지향과 테스트하기 쉬운 코드를 위헤서는 jpa가 의미없는게 아닌가하는 생각이 들어요
이전에 혼자 ddd, 헥사고날 아키텍처를 공부하면서 느꼈던게객체지향적인 코드 + 테스트하기 용이한 코드를 작성하기 위해서는 결국 domain layer와 persistence layer의 분리가 필수적인데jpa entity와 domain entity를 완전히 분리했을 때 JPA가 mybatis나 jdbc template를 사용하는 것과 비교해 가지는 강점이 있는지 잘 모르겠습니다..그나마 jpa entity와 domain entity를 분리하지 않는다면 어떻게든 온몸 비틀기로 그나마 테스트하기 용이하고 객체지향스러운 코드를 작성해볼 수는 있지만 결국 복잡한 로직에서는 쿼리 때문에 문제가 생기고 ㅜ지식 공유자님께서는 이 문제에 대해 어떻게 생각하시나요?
-
해결됨Java/Spring 주니어 개발자를 위한 오답노트
c. Collection,Map 질문
Collection.Map의 Good 케이스를 알 수 있을까요?맵을 사용할 때 맵 안에 맵이 있고 이런 형태를 사용하지 않는게 좋은건지 아니면 따로 dto로 변환해서 사용해야하는건지 구분이 안 가서 질문 드립니다 ! 지정된 scope를 넘나들지 않는다는 것도 이해가 가지 않습니다 ㅠㅠ조금만 더 쉽게 설명 붙여주시면 감사드리겠습니다!
-
미해결Practical Testing: 실용적인 테스트 가이드
외부 세계에 영향을 주는 코드
관측할 때마다 다른 값의 의존하는 코드는즉, 현재시각, 랜덤 값 등등은 이해 하겠는데외부 세계에 영향을 주는 코드는 어떤 건지 이해가 잘 안되서요.혹시 간단한 예제를 들어주실수 있으실까요?
-
해결됨부트캠프에서 알려주지 않는 것들 (리액트) 1편
마지막 onSubmit 에러체크 문제
에러체크할 때 나머지값이 없어도 submit이 되는 문제가 있습니다.<InfoContext.Provider value={{ value: info, setValue: setInfo, error, setError: (e) => setError({...error, ...e}) }}> <Form onSubmit={onSubmit}> <TextField source="name" label="이름" validate={[minLength(3), maxLength(6)]} /> <TextField source="password" label="패스워드" validate={[minLength(6), maxLength(12)]} /> <CheckboxField source="confirm" label="위 내용이 제출됩니다 동의하십니까?" validate={[checked]} /> </Form> </InfoContext.Provider>위 코드에서 setError update해주는 로직을 // before setError: (e) => setError({...error, ...e}) // after setError: (e) => setError(prev => ({...prev, ...e}))아래와 같은 형식으로 바꿔주면, 리팩토링 이전과 같이 동작을 하게됩니다.batch의 문제인지, 불변성의 문제인지 정확히 모르겠네요. 설명해주시면 감사감사!
-
미해결스프링부트 JUnit 테스트 - 시큐리티를 활용한 Bank 애플리케이션
회원가입 컨트롤러 만들기 - User.java의 role
@Enumerated(EnumType.STRING)@Column(nullable = false)public UserEnum role; //ADMIN,CUSTOMERUser.java의 role이 위외 같이 nullable=false로 되어있다보니 에러가 뜨는것 같습니다.UserController의 UserRespDto userRespDto = userService.signIn(userReqDto);를 실행했을때UserService의 34번 라인에서 아래와 같이 에러가 뜨네요강사님 코드랑 조금 다른 부분이 있긴합니다. dto에 빌더패턴을 사용중이긴 한데... 음 이거때문에 에러를 뱉는건 아닌거 같긴 합니다.물론, User.java에서 아래와 같이 코드를 수정해주면 문제없이 잘됩니다.@Enumerated(EnumType.STRING)@Columnpublic UserEnum role; //ADMIN,CUSTOMER저만 안되는 부분인지.. 아니면 (nullable = false)를 빼고하는게 맞는건지 궁금해서 질문드려요!감사합니다.
-
미해결따라하며 배우는 리액트 A-Z[19버전 반영]
컴파일 에러
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. const movieId = request.data.result[Math.floor(Math.random() * request.data.results.length)].id; 부분 작성 후 컴파일 시 리액트에서 Cannot read properties of undefined 에러가 발생합니다. 하나가 아니라 여러개 발생하는데 조치방법이 있을까요?
-
해결됨부트캠프에서 알려주지 않는 것들 (리액트) 1편
코드샌드박스 주소
강의하시는 예제를 코드샌드박스에서 열고싶은데 링크가 어디있나요??