묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
MemberServiceV3_3 테스트 코드 질문 있습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]위는 MemberServiceV3_3 코드의 @Transactional를 사용하는 메소드 부분이고 아래는 MemberServiceV3_3Test 코드입니다.package hello.jdbc.service; import hello.jdbc.domain.Member; import hello.jdbc.repository.MemberRepositoryV3; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.transaction.PlatformTransactionManager; import javax.sql.DataSource; import java.sql.SQLException; import static hello.jdbc.connection.ConnectionConst.*; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; /** * 트랜잭션 - @Transactional AOP */ @Slf4j @SpringBootTest //스프링테스트 어노테이션이 있으면 이 테스트에서 //스프링부트가 이 테스트에서 스프링 컨테이너를 만들고 필요한 스프링 빈을 전부 등록하고 스프링 빈에 대한 의존관계 주입도 받을 수 있게 된다 class MemberServiceV3_3Test { public static final String MEMBER_A = "memberA"; public static final String MEMBER_B = "memberB"; public static final String MEMBER_EX = "ex"; @Autowired // 의존관계 주입을 받아서 사용한다. private MemberRepositoryV3 memberRepository; @Autowired private MemberServiceV3_3 memberService; @TestConfiguration static class TestConfig{ @Bean DataSource dataSource(){ return new DriverManagerDataSource(URL,USERNAME,PASSWORD); } @Bean PlatformTransactionManager transactionManager(){ return new DataSourceTransactionManager(dataSource()); } @Bean MemberRepositoryV3 memberRepositoryV3(){ return new MemberRepositoryV3(dataSource()); } @Bean MemberServiceV3_3 memberServiceV3_3(){ return new MemberServiceV3_3(memberRepositoryV3()); } } @AfterEach void after() throws SQLException { memberRepository.delete(MEMBER_A); memberRepository.delete(MEMBER_B); memberRepository.delete(MEMBER_EX); } @Test @DisplayName("정상 이체") void accountTransfer() throws SQLException { //given Member memberA = new Member(MEMBER_A, 10000); Member memberB = new Member(MEMBER_B, 10000); memberRepository.save(memberA); memberRepository.save(memberB); //when memberService.accountTransfer(memberA.getMemberId(), memberB.getMemberId(), 2000); //then Member findMemberA = memberRepository.findById(memberA.getMemberId()); Member findMemberB = memberRepository.findById(memberB.getMemberId()); assertThat(findMemberA.getMoney()).isEqualTo(8000); assertThat(findMemberB.getMoney()).isEqualTo(12000); } @Test @DisplayName("이체중 예외 발생") void accountTransferEx() throws SQLException { //given Member memberA = new Member(MEMBER_A, 10000); Member memberEx = new Member(MEMBER_EX, 10000); memberRepository.save(memberA); memberRepository.save(memberEx); //when assertThatThrownBy(() -> memberService.accountTransfer(memberA.getMemberId(), memberEx.getMemberId(), 2000)) .isInstanceOf(IllegalStateException.class); //then Member findMemberA = memberRepository.findById(memberA.getMemberId()); Member findMemberEx = memberRepository.findById(memberEx.getMemberId()); //memberA의 돈이 롤백 되어야함 assertThat(findMemberA.getMoney()).isEqualTo(10000); assertThat(findMemberEx.getMoney()).isEqualTo(10000); } }저는 지금까지는 원본 코드와 테스트 코드가 따로 따로라고 생각했습니다. 근데 강의에서 원본 코드의 @Transactional을 사용 했을 때와, @Transactional을 주석 처리해 원본 코드를 수정했을 때. 테스트 코드의 결과가 다르게 변하더라구요. 이런 결과가 왜 발생하는건가요?테스트 코드는 원본 코드에 영향을 받는건가요?만약, 영향을 받는다면 어떤 범위까지 영향을 받는건가요? 설명 부탁드립니다!
-
해결됨쥬쥬와 함께 하루만에 끝내는 스프링 테스트
JaCoCo 레포트 파일이 안생깁니다.
안녕하세요. 강의 잘 듣고 있습니다.노션에 있는 그대로 코드를 작성했는데 아무리 테스트가 끝나도jacoco 안에 파일이 안생깁니다. 그래서 terminal 에서 ./gradlew jacocoTestReport 를 했는데BUILD SUCCESSFUL 은 나오는데 파일이 안생기는데 이유를 모르겠습니다!
-
미해결Practical Testing: 실용적인 테스트 가이드
코틀린 관련 질문!
강의에서 코틀린을 간간히 언급을 해주시는데, 실무에서는 코틀린을 사용중이신건지 궁금해서 글을 남기게 되었습니다! 코틀린을 사용하신다면, 어떤 상황에서는 자바를 사용하고, 어떤 상황에서는 코틀린을 사용하면 좋을지 추천해주시면 좋을 것 같아서 질문을 남겨봅니다! 강의 너무 잘보고 있습니다 감사합니다!
-
미해결스프링 시큐리티 OAuth2
소셜로그인 정보가져오기
강사님 수업을 보면 정보를 다 가지고 오는 것을 볼 수 있는데 package com.example.oauth.config.OAuth2; import org.springframework.security.core.authority.SimpleGrantedAuthority; import java.util.List; import java.util.Map; public interface ProviderUser { String getId(); String getUserName(); String getPassword(); String getEmail(); String getProvider(); List<SimpleGrantedAuthority> getAuthorities(); Map<String, Object> getAttributes(); }package com.example.oauth.config.OAuth2; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.core.user.OAuth2User; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.stream.Collectors; // 여기는 공통적인 부분만 추상화해서 모아놓은 곳이다. // Google, Naver에서 다른 부분들은 따로 만들어줄 것이다. public abstract class OAuth2ProviderUser implements ProviderUser{ private Map<String, Object> attributes; private OAuth2User oAuth2User; private ClientRegistration clientRegistration; public OAuth2ProviderUser(Map<String, Object> attributes, OAuth2User oAuth2User, ClientRegistration clientRegistration) { this.attributes = attributes; this.oAuth2User = oAuth2User; this.clientRegistration = clientRegistration; } @Override public String getPassword() { return UUID.randomUUID().toString(); } @Override public String getEmail() { return (String) getAttributes().get("email"); } @Override public List<SimpleGrantedAuthority> getAuthorities() { return oAuth2User.getAuthorities().stream() .map(authority -> new SimpleGrantedAuthority(authority.getAuthority())) .collect(Collectors.toList()); } @Override public String getProvider() { return clientRegistration.getRegistrationId(); } @Override public Map<String, Object> getAttributes() { return attributes; } }package com.example.oauth.config.OAuth2; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.core.user.OAuth2User; import java.util.Map; public class NaverUser extends OAuth2ProviderUser{ public NaverUser(OAuth2User oAuth2User, ClientRegistration clientRegistration) { super(( Map<String, Object>) oAuth2User.getAttributes().get("response"), oAuth2User, clientRegistration); } @Override public String getId() { return (String) getAttributes().get("id"); } @Override public String getUserName() { return (String) getAttributes().get("name"); } }package com.example.oauth.config.OAuth2; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.core.user.OAuth2User; public class GoogleUser extends OAuth2ProviderUser{ public GoogleUser(OAuth2User oAuth2User, ClientRegistration clientRegistration) { // 사용자의 정보는 oAuth2User.getAttributes() 여기에 담겨져 있다. // 여기는 클레임 형식 즉, Map 형식으로 되어 있다. super(oAuth2User.getAttributes(), oAuth2User, clientRegistration); } @Override // 식별자의 역할 public String getId() { return (String) getAttributes().get("sub"); } @Override // 유저 id public String getUserName() { return (String) getAttributes().get("name"); } }package com.example.oauth.config.OAuth2; import com.example.oauth.repository.UserRepository; import com.example.oauth.service.UserService; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; import org.springframework.security.oauth2.client.userinfo.OAuth2UserService; import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.stereotype.Service; @Service // OAuth2UserService : Spring Security에서 OAuth 2.0을 사용하여 인증한 사용자 정보를 가져오기 위한 인터페이스입니다. // 이 인터페이스를 구현하여 사용자 정보를 가져오는 방법을 정의하고, // OAuth 2.0 프로바이더(예: Google, Facebook, GitHub 등)로부터 인증된 사용자 정보를 추출할 수 있습니다. // OAuth2UserRequest : 이 객체는 OAuth 2.0 클라이언트 정보, 권한 부여 코드, 액세스 토큰 등을 포함합니다. // 이 정보를 사용하여 사용자 정보를 요청하고 처리할 수 있습니다. // OAuth2User : OAuth 2.0 프로바이더(인증 제공자)로부터 가져온 인증된 사용자 정보를 나타냅니다. // 이 정보는 사용자의 프로필 데이터, 권한(스코프), 사용자 ID 등을 포함할 수 있습니다. public class CustomOAuth2UserService extends AbstractOAuth2UserService implements OAuth2UserService<OAuth2UserRequest, OAuth2User> { public CustomOAuth2UserService(UserRepository userRepository, UserService userService) { super(userRepository, userService); } @Override public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { // ClientRegistration은 Spring Security에서 OAuth 2.0 또는 OpenID Connect (OIDC) 클라이언트 // 애플리케이션의 등록 정보를 나타내는 클래스입니다. 클라이언트 애플리케이션의 설정 및 속성을 포함합니다. // userRequest.getClientRegistration()은 인증 및 인가된 사용자 정보를 가져오는 // Spring Security에서 제공하는 메서드입니다. ClientRegistration clientRegistration = userRequest.getClientRegistration(); OAuth2UserService<OAuth2UserRequest, OAuth2User> oAuth2UserService = new DefaultOAuth2UserService(); OAuth2User oAuth2User = oAuth2UserService.loadUser(userRequest); // 여기에는 구글, 네이버 정보가 담겨져 있다. ProviderUser providerUser = super.providerUser(clientRegistration, oAuth2User); // 회원가입 super.register(providerUser, userRequest); return oAuth2User; } }package com.example.oauth.config.OAuth2; import com.example.oauth.entity.UserEntity; import com.example.oauth.repository.UserRepository; import com.example.oauth.service.UserService; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.stereotype.Service; @Service @Getter @RequiredArgsConstructor @Log4j2 // 사용자 등록과 어떤 사용자인지 알아볼 수 있는 곳 public abstract class AbstractOAuth2UserService { private final UserRepository userRepository; private final UserService userService; protected void register(ProviderUser providerUser, OAuth2UserRequest userRequest) { UserEntity findUser = userRepository.findByUserName(providerUser.getUserName()); if(findUser == null) { String registrationId = userRequest.getClientRegistration().getRegistrationId(); userService.register(registrationId, providerUser); } else { log.info("user : " + findUser); } } protected ProviderUser providerUser(ClientRegistration clientRegistration, OAuth2User oAuth2User) { String registrationId = clientRegistration.getRegistrationId(); if(registrationId.equals("google")) { return new GoogleUser(oAuth2User, clientRegistration); } else if(registrationId.equals("naver")) { return new NaverUser(oAuth2User, clientRegistration); } else { return null; } } }이거를 REST 방식으로 하려고 컨트롤러 // 소셜 로그인 @GetMapping("/api/v1/user/success") public ResponseEntity<?> socialLogin(Authentication authentication, @AuthenticationPrincipal OAuth2User oAuth2User) { OAuth2AuthenticationToken oAuth2AuthenticationToken = (OAuth2AuthenticationToken) authentication; if (oAuth2AuthenticationToken != null) { ResponseEntity<?> oAuth2Login = memberService.login(oAuth2AuthenticationToken, oAuth2User); return ResponseEntity.ok().body(oAuth2Login); } else { return ResponseEntity.badRequest().build(); } }서비스 // 소셜 로그인 public ResponseEntity<?> login(OAuth2AuthenticationToken oAuth2AuthenticationToken, OAuth2User oAuth2User) { Map<String, Object> attributes = oAuth2User.getAttributes(); log.info("attributes : " + attributes); String authorizedClientRegistrationId = oAuth2AuthenticationToken.getAuthorizedClientRegistrationId(); String email = null; TokenDTO jwt = null; if (authorizedClientRegistrationId.equals("google")) { email = (String) attributes.get("email"); log.info("email : " + email); jwt = createJWT(email); log.info("jwt : " + jwt); } else if (authorizedClientRegistrationId.equals("naver")) { Map<String, Object> response = (Map) attributes.get("response"); email = (String) response.get("email"); jwt = createJWT(email); log.info("jwt : " + jwt); } else { log.info("아무런 정보를 받지 못했습니다."); } return ResponseEntity.ok().body(jwt); } private TokenDTO createJWT(String email) { MemberEntity findUser = memberRepositroy.findByEmail(email); List<GrantedAuthority> authoritiesForUser = getAuthoritiesForUser(findUser); TokenDTO tokenForOAuth2 = jwtProvider.createTokenForOAuth2(email, authoritiesForUser); TokenEntity findToken = tokenRepository.findByMemberEmail(tokenForOAuth2.getMemberEmail()); if (findToken == null) { TokenEntity tokenEntity = TokenEntity.toTokenEntity(tokenForOAuth2); tokenRepository.save(tokenEntity); log.info("token : " + tokenForOAuth2); } else { tokenForOAuth2 = TokenDTO.builder() .id(findToken.getId()) .grantType(tokenForOAuth2.getGrantType()) .accessToken(tokenForOAuth2.getAccessToken()) .refreshToken(tokenForOAuth2.getRefreshToken()) .memberEmail(tokenForOAuth2.getMemberEmail()) .build(); TokenEntity tokenEntity = TokenEntity.toTokenEntity(tokenForOAuth2); tokenRepository.save(tokenEntity); } return tokenForOAuth2; }이렇게 구성을 했는데 JWT는 제외하고 public ResponseEntity<?> socialLogin(Authentication authentication,@AuthenticationPrincipal OAuth2User oAuth2User) { 이거로 정보를 가지고 오려고 했는데 정보를 안가지고 와지고 계속 JWT 검증 로직에 걸려서 잘못된 JWT라고 뜹니다 ㅠㅠ package com.example.study01.config.jwt; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.util.StringUtils; import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Log4j2 @RequiredArgsConstructor public class JwtAuthenticationFilter extends OncePerRequestFilter { public static final String HEADER_AUTHORIZATION = "Authorization"; private final JwtProvider jwtProvider; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { HttpServletRequest httpServletRequest = (HttpServletRequest) request; // request header에서 JWT를 추출 // 요청 헤더에서 JWT 토큰을 추출하는 역할 String jwt = resovleToken(httpServletRequest); log.info("jwt in JwtAuthenticationFilter : " + jwt); // 어떤 경로로 요청을 했는지 보여줌 String requestURI = httpServletRequest.getRequestURI(); log.info("uri JwtAuthenticationFilter : " + requestURI); if(StringUtils.hasText(jwt) && jwtProvider.validateToken(jwt)) { // 토큰이 유효할 경우 토큰에서 Authentication 객체를 가지고 와서 SecurityContext에 저장 Authentication authentication = jwtProvider.getAuthentication(jwt); log.info("authentication in JwtAuthenticationFilter : " + authentication); // Spring Security의 SecurityContextHolder를 사용하여 현재 인증 정보를 설정합니다. // 이를 통해 현재 사용자가 인증된 상태로 처리됩니다. // 위에서 jwtProvider.getAuthentication(jwt)가 반환이 UsernamePasswordAuthenticationToken로 // SecurityContext에 저장이 되는데 SecurityContextHolder.getContext().setAuthentication(authentication); // 처리를 하는 이유는 다음과 같다. /* * 1. 인증 정보 검증: JWT 토큰이나 다른 인증 정보를 사용하여 사용자를 식별하고 * 권한을 확인하기 위해서는 토큰을 해독하여 사용자 정보와 권한 정보를 추출해야 합니다. * 이 역할은 jwtProvider.getAuthentication(jwt)에서 수행됩니다. * 이 메서드는 JWT 토큰을 분석하여 사용자 정보와 권한 정보를 추출하고, 해당 정보로 인증 객체를 생성합니다. * * 2. 인증 정보 저장: * 검증된 인증 객체를 SecurityContextHolder.getContext().setAuthentication(authentication);를 * 사용하여 SecurityContext에 저장하는 이유는, Spring Security에서 현재 사용자의 인증 정보를 * 전역적으로 사용할 수 있도록 하기 위함입니다. 이렇게 하면 다른 부분에서도 현재 사용자의 인증 정보를 사용할 수 있게 되며, * Spring Security가 제공하는 @AuthenticationPrincipal 어노테이션을 통해 현재 사용자 정보를 편리하게 가져올 수 있습니다. * */ SecurityContextHolder.getContext().setAuthentication(authentication); } else { log.error("유효한 JWT가 없습니다. : " + requestURI); } filterChain.doFilter(request, response); } // 토큰을 가져오기 위한 메소드 // Authorization로 정의된 헤더 이름을 사용하여 토큰을 찾고 // 토큰이 "Bearer "로 시작하거나 "Bearer "로 안온 것도 토큰 반환 private String resovleToken(HttpServletRequest httpServletRequest) { String token = httpServletRequest.getHeader(HEADER_AUTHORIZATION); // 토큰이 포함하거나 Bearer 로 시작하면 true if(StringUtils.hasText(token) && token.startsWith("Bearer ")) { return token.substring(7); } else if(StringUtils.hasText(token)) { return token; } else { return null; } } }이럴 경우는 어떻게 해야하나요... 컨트롤러에서 정보를 가지고 와서 그 정보로 JWT를 만들어 반환하려고 하는데 정보를 가지고 오는게 계속 실패를 해서...
-
미해결Practical Testing: 실용적인 테스트 가이드
테스트가 무시되는 상황이 일어납니다.
안녕하세요!수업과 최대한 유사하게 코드를 작성해왔는데,테스트가 무시되는 상황이 발생하여 질문 올립니다. 에러메세지대로 @SpringBootConfiguration도 추가해보고,구글링도 해봤는데 해결이 되지 않아 질문 올립니다 죄송합니다. 테스트가 무시되었습니다.java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test at org.springframework.util.Assert.state(Assert.java:76) at org.springframework.boot.test.context.SpringBootTestContextBootstrapper.getOrFindConfigurationClasses(SpringBootTestContextBootstrapper.java:237) at org.springframework.boot.test.context.SpringBootTestContextBootstrapper.processMergedContextConfiguration(SpringBootTestContextBootstrapper.java:152) at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildMergedContextConfiguration(AbstractTestContextBootstrapper.java:393) at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildDefaultMergedContextConfiguration(AbstractTestContextBootstrapper.java:309) at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildMergedContextConfiguration(AbstractTestContextBootstrapper.java:262) at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildTestContext(AbstractTestContextBootstrapper.java:107) at org.springframework.boot.test.context.SpringBootTestContextBootstrapper.buildTestContext(SpringBootTestContextBootstrapper.java:102) at org.springframework.test.context.TestContextManager.<init>(TestContextManager.java:137) at org.springframework.test.context.TestContextManager.<init>(TestContextManager.java:122) at org.junit.jupiter.engine.execution.ExtensionValuesStore.lambda$getOrComputeIfAbsent$4(ExtensionValuesStore.java:86) at org.junit.jupiter.engine.execution.ExtensionValuesStore$MemoizingSupplier.computeValue(ExtensionValuesStore.java:223) at org.junit.jupiter.engine.execution.ExtensionValuesStore$MemoizingSupplier.get(ExtensionValuesStore.java:211) at org.junit.jupiter.engine.execution.ExtensionValuesStore$StoredValue.evaluate(ExtensionValuesStore.java:191) at org.junit.jupiter.engine.execution.ExtensionValuesStore$StoredValue.access$100(ExtensionValuesStore.java:171) at org.junit.jupiter.engine.execution.ExtensionValuesStore.getOrComputeIfAbsent(ExtensionValuesStore.java:89) at org.junit.jupiter.engine.execution.ExtensionValuesStore.getOrComputeIfAbsent(ExtensionValuesStore.java:93) at org.junit.jupiter.engine.execution.NamespaceAwareStore.getOrComputeIfAbsent(NamespaceAwareStore.java:61) at org.springframework.test.context.junit.jupiter.SpringExtension.getTestContextManager(SpringExtension.java:294) at org.springframework.test.context.junit.jupiter.SpringExtension.beforeAll(SpringExtension.java:113) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeBeforeAllCallbacks$10(ClassBasedTestDescriptor.java:381) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeBeforeAllCallbacks(ClassBasedTestDescriptor.java:381) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:205) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:80) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:148) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86) at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86) at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53) at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57) at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38) at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11) at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35) at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)종료 코드 255(으)로 완료된 프로세스
-
미해결스프링 시큐리티 OAuth2
이제 spring boot 버전 3으로 가는데
spring boot 3 버전은spring security 디폴트가 6로 설정되어 있더라구요spring security 6 진행시에 Oauth2 강의 진행에 문제가 없을까요?? 여러가지로 바뀐게 많아서
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
회원목록 열람 실패 해결관련 문의사항
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]여기에 질문 내용을 남겨주세요. 회원 목록 출력?시 에러 발생하여 출력 되지 않아 해결 해보았습니다. 해당 문제를 이렇게 해결 하는게 적절한 방법 인지 확인 부탁드립니다! 현상1. 회원 가입 진행 하지 않고 (데이터 없음), 회원 목록 접근시 정상 화면 송출2. 회원 가입 진행 후, 회원 목록 접근 시, 에러 발생 에러 내용생각한 원인 및 해결 방법Member 클래스 내, 접근 제한자가 Private로 설정된 id와 name 변수를 getId, getName이 아닌 방법으로 꺼내와서 문제 발생. getId, GetName매서드로 접근시 정상 동작 Member 클래스에서 Getter And Setter로 생성하지 않고 직접 타이핑 해서 발생.
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
2강 질문
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]java 11설치후 Springboot 2.7.16을 깔았는데 Run할수있는 표시도 안나오고자꾸 저렇게 오류가 뜹니다 뭐가 문제일까요?
-
해결됨쥬쥬와 함께 하루만에 끝내는 스프링 테스트
localstack 이 deprecated 되서 이렇게 수정했습니다.
안녕하세요. 강의 잘 듣고 있습니다.localstack 이 deprecated 가 되어서 조금 수정이 필요해서 고쳐보았습니다. 노션에도 의존성에 버전을 작성해야 동작을 해야 하더라구요. testImplementation "org.testcontainers:localstack:1.19.0" DockerImageName imageName = DockerImageName.parse("localstack/localstack:0.11.2"); aws = (new LocalStackContainer(imageName)) .withServices(LocalStackContainer.Service.S3) .withStartupTimeout(Duration.ofSeconds(600)); aws.start(); 전 이렇게 수정해서 고쳤습니다!
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
프로젝트 hello 실행했을때의 오류
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]4:12:44 PM: 실행 중 ':classes'...> Task :compileJava FAILED1 actionable task: 1 executedFAILURE: Build failed with an exception.* What went wrong:Execution failed for task ':compileJava'.> invalid source release: 11* Try:> Run with --stacktrace option to get the stack trace.> Run with --info or --debug option to get more log output.> Run with --scan to get full insights.* Get more help at https://help.gradle.orgBUILD FAILED in 1s4:12:45 PM: 실행이 완료되었습니다 ':classes'.이런 오류와 함께 빌드가 실패합니다. 뭐가 문젠지 모르겠어요. 한번 빌드를 실행해서 됐었고, 코드를 실행하려고 하니까 빌드가 실패했다는 오류가 뜹니다
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
스프링 부트 버전 어느것을 선택해야하나요?
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용] 여기에서 버전을 어느것을 선택해야하나요?
-
미해결자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
서버에 연결이 너무 느려서 안되는데
시간이 초과되어서 안되는데 인바운드 규칙엔 8080, 22,등등 모두 추가해둔 상태입니다. 혹시보이는 사진이 문제일까 싶어서 첨부합니다.
-
미해결Java/Spring 테스트를 추가하고 싶은 개발자들의 오답노트
안녕하세요. 강의 수강 후, 토이프로젝트에 적용해보다가 Fake Repository에 관해 궁금한 것이 생겨 질문드립니다!
안녕하세요. 우선 강의 너무 잘 들었습니다.설계를 개선하며 소형테스트를 풍부하게 작성할 수 있다는 것을 보고 이를 체화하려고 공부중인데요,강의에서 배운것을 적용하다가 막힌 곳이 있어서 질문드립니다.우선, 저는 강의와 유사하게 Repository를 추상화해서 프로덕션(~RepositoryImpl)과 테스트 환경(Fake~Repository)을 다르게 가져가고 있고, 막힌 부분은 아래와 같습니다.프로덕션에서 groupBy를 사용하고, Dto로 바로 조회하는 방식으로 프로덕션 Repository에 코드를 작성한 부분이 있는데,이를 Fake Repository에서 작성하려니까 막막하더라구요왜 FakeRepository에 작성하려 하냐면, 제가 이해하기로는 FakeRepository를 구현해야 Service 레이어를 테스트할 때, 소형테스트로 작성할 수 있다고 이해를 했기 때문입니다. 막힌 부분에서 여러 고민해보다가, 다양한 조건절과 그룹핑이 들어간 쿼리는 어떻게 Fake Repository에 작성해서 테스트할 수 있을까? 하는 궁금증이 생겼습니다. 그래서 질문입니다.Fake Repository를 사용해서 일부 Service 레이어의 로직을 테스트할 수 있지만, 좀 더 복잡한 쿼리들은 Fake로 구현(stream, filter등을 사용해서)하기 어려우니, Fake로 구현하지 않고 중형 테스트로 테스트한다.그리고 위의 기준이 소형테스트로 테스트할 지, 중형테스트로 테스트할 지 고려할 기준이 된다..?저는 위와같이 생각이 이어지는데, 혹시 옳은 생각일까요? 아님 열심히 Fake로 구현을 해봐야하는 것일까요?그것도 아니라면 다른 방법이 있을까요? 강사님은 복잡한 쿼리들을 어떻게 하시는지 궁금합니다..!열심히 강의해주셨는데, 막상 적용해보려니 쉽지 않아서 민망합니다..답변 미제공 강의지만, 호옥시나 하는 마음에 질문 남깁니다.🥹좋은 강의 감사드립니다
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
build.gradle 호환 에러
start.spring.io 에서 generate 하고 빌드를 하는데 스프링부트 플러그인과 gradle 버전이 호환이 안된다고 에러가 뜨는데 그러면 버전을 낮춰서라도 실행이 되면 상관없나요? 버전을 낮추면 실행은 되는데 이후의 강의를 따라가는데 뭔가 문제가 생길까 싶어서 여쭤봅니다
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
윈도우 빌드오류요
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]할 수 있는 설정은 전부 jdk 17로 했구요, 컴파일 설정도 17로 해놓았습니다. 3짤에 project탭도 17로 설정되어있습니다. java version 도 보이시는대로 17인데..자꾸 이런 오류 메세지가 뜹니다. Incompatible because this component declares a component, compatible with Java 17 and the consumer needed a component, compatible with Java 11 라구요. 아 세번째 이미지에서 .gradle과 build 폴더는 원래대로 다시 exclude로 빨간색 되어있는 상태입니다.뭐가 문제인지 모르겠네요.
-
미해결스프링 DB 2편 - 데이터 접근 활용 기술
master, replica 구성할 때 EntityManagerFactory 빈 등록 관련 질문드립니다.
안녕하세요.강의 내용과 조금 별개의 질문일 수 있는데 마땅히 물어볼 곳이 없어 질문드리게 되었습니다.@Transactional(read-only) 로 설정했을 때, replication db 에서 조회하도록 Master, Replica 데이터 소스를 구성해보려고 하는데요,Master 와 Replica 각각의 데이터소스와 AbstractRoutingDataSource를 상속받는 routingDataSource 를 빈으로 등록 후,EntityManagerFactory 도 빈으로 등록했습니다.@Bean public EntityManagerFactory entityManagerFactory(DataSource dataSource) { LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); factory.setPackagesToScan("com.example.domain"); factory.setDataSource(dataSource); HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter(); factory.setJpaVendorAdapter(jpaVendorAdapter); factory.afterPropertiesSet(); return factory.getObject(); }이렇게 모두 설정하면 동작은 잘 되는데 application.yml 에 설정한 auto-ddl 이나 show_sql, form_sql 과 같은 프로퍼티 설정을 읽어오지 못하더라구요.그래서 아래와 같이 HibernateJpaVendorAdapter 에 직접 설정을 추가해줘야지 동작했습니다.HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter(); jpaVendorAdapter.setGenerateDdl(true); jpaVendorAdapter.setShowSql(true);그런데 이렇게 직접적으로 설정값을 넣어서 구성하면 profile 에 따라 설정 값 적용을 분리하지 못하게되는데,그럼 아래와 같이 Properties 를 직접 가져와서 설정 값에 넣어줘야하는걸까요? 이러한 방식이 맞는지 의문이 들어서 질문하게 되었습니다. HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter(); jpaVendorAdapter.setGenerateDdl(jpaProperties.isGenerateDdl()); jpaVendorAdapter.setShowSql(jpaProperties.isShowSql()); factory.setJpaVendorAdapter(jpaVendorAdapter);그리고 구글링 했을 때 블로그 예제들은 현업에서 정말 사용하는 구성인지 Master, replica 를 설정하는데 참고할만한 좋은 레퍼런스 있으면 추천 부탁드립니다.
-
미해결스프링 DB 2편 - 데이터 접근 활용 기술
EntityManager 빈 자동주입
EntityManager Configuration 파일에서 선언할 때@RequiredArgsConstructor 어노테이션을 제거하셨는데 어떻게 자동주입이 된것이죠?
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
profile 관련 오류 문의
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]스프링부트 3.1.4 버전에 jdk 17로 프로젝트 생성했는데, 계속해서 아래와 같은 에러가 발생합니다. No active profile set, falling back to 1 default profile: "default" 구글링 해서 다양한 방법으로 시도해봤지만 해결이 되지 않아 글 남겨봅니다. *** 빌드 및 실행, 테스트 실행도 Gradle, 인텔리제이로 해봐도 같은 에러가 발생하고, yml을 저렇게 설정하고 해도 dev profile을 읽긴 하나 서버 접속은 안되는 상황입니다.
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
데이터베이스 방언 설정
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]자바 ORM 표준 JPA 프로그래밍에서는 maven으로 빌드 툴을 선택하였고 DB 방언을 dialect를 통해서 직접 설정(ex.h2.dialect)해주었는데 gradle로 할때는 따로 설정하는 부분이 영상에 안보이는데 gradle에서 JPA 방언 설정 과정에 대해서 궁금합니다.
-
미해결[NarP Series] MVC 프레임워크는 내 손에 [나프2탄]
안녕하세요 맥북세팅 질문드려요
안녕하세요 혹시 제가 맥북인데 강의는 윈도우로만 세팅 되어있는거같아서 그런데 맥북으로는 강의 듣는데 지장이있을까요?