인프런 커뮤니티 질문&답변

정윤영님의 프로필 이미지
정윤영

작성한 질문수

실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발

회원 서비스 개발

MemberServiceTest를 실행하면 에러가 뜹니다.

작성

·

337

0

[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오) 예
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 아니오
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)

[질문 내용]
1. MemberServiceTest를 실행하면 에러가 뜹니다.

@RunWith는 Junit5로 넘어오면서 없어져 넣진 않았습니다.

 

01:32:35.817 [Test worker] INFO org.springframework.test.context.support.AnnotationConfigContextLoaderUtils -- Could not detect default configuration classes for test class [com.boardproject.service.MemberServiceTest]: MemberServiceTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.

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.findConfigurationClass(SpringBootTestContextBootstrapper.java:246)

at org.springframework.boot.test.context.SpringBootTestContextBootstrapper.getOrFindConfigurationClasses(SpringBootTestContextBootstrapper.java:233)

at org.springframework.boot.test.context.SpringBootTestContextBootstrapper.processMergedContextConfiguration(SpringBootTestContextBootstrapper.java:150)

at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildMergedContextConfiguration(AbstractTestContextBootstrapper.java:354)

at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildDefaultMergedContextConfiguration(AbstractTestContextBootstrapper.java:270)

at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildMergedContextConfiguration(AbstractTestContextBootstrapper.java:218)

at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildTestContext(AbstractTestContextBootstrapper.java:108)

at org.springframework.boot.test.context.SpringBootTestContextBootstrapper.buildTestContext(SpringBootTestContextBootstrapper.java:111)

at org.springframework.test.context.TestContextManager.<init>(TestContextManager.java:142)

at org.springframework.test.context.TestContextManager.<init>(TestContextManager.java:126)

at org.junit.platform.engine.support.store.NamespacedHierarchicalStore.lambda$getOrComputeIfAbsent$5(NamespacedHierarchicalStore.java:147)

at org.junit.platform.engine.support.store.NamespacedHierarchicalStore$MemoizingSupplier.computeValue(NamespacedHierarchicalStore.java:372)

at org.junit.platform.engine.support.store.NamespacedHierarchicalStore$MemoizingSupplier.get(NamespacedHierarchicalStore.java:361)

at org.junit.platform.engine.support.store.NamespacedHierarchicalStore$StoredValue.evaluate(NamespacedHierarchicalStore.java:308)

at org.junit.platform.engine.support.store.NamespacedHierarchicalStore$StoredValue.access$200(NamespacedHierarchicalStore.java:287)

at org.junit.platform.engine.support.store.NamespacedHierarchicalStore.getOrComputeIfAbsent(NamespacedHierarchicalStore.java:149)

at org.junit.platform.engine.support.store.NamespacedHierarchicalStore.getOrComputeIfAbsent(NamespacedHierarchicalStore.java:168)

at org.junit.jupiter.engine.execution.NamespaceAwareStore.lambda$getOrComputeIfAbsent$3(NamespaceAwareStore.java:66)

at org.junit.jupiter.engine.execution.NamespaceAwareStore.accessStore(NamespaceAwareStore.java:90)

at org.junit.jupiter.engine.execution.NamespaceAwareStore.getOrComputeIfAbsent(NamespaceAwareStore.java:65)

at org.springframework.test.context.junit.jupiter.SpringExtension.getTestContextManager(SpringExtension.java:366)

at org.springframework.test.context.junit.jupiter.SpringExtension.beforeAll(SpringExtension.java:131)

at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeBeforeAllCallbacks$12(ClassBasedTestDescriptor.java:396)

at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)

at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeBeforeAllCallbacks(ClassBasedTestDescriptor.java:396)

at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:212)

at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:85)

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.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:119)

at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:94)

at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:89)

at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62)

at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)

at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.base/java.lang.reflect.Method.invoke(Method.java:568)

at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)

at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)

at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)

at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)

at jdk.proxy1/jdk.proxy1.$Proxy2.stop(Unknown Source)

at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)

at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)

at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)

at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)

at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)

at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113)

at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)

at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)

at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)

 

 

답변 4

0

보내주신 코드 확인해봤습니다!

패키지 위치를 조정해주십쇼!

image정윤영님께서는 @SpringBootApplication이 붙은 JpashopApplication이 com.boardproject.jpashop 내부에 있습니다.

그리고 repository나 service는 그 외부에 만드셨습니다. Repository나 Service 등이 정상적으로 작동하려면 JpashopApplication이 있는 패키지와 같은 층위에 있어야 합니다.

image이렇게 바꿔주세요! (강의 영상도 자세히 보시면 jpashop 내에 domain, repository, service 패키지가 위치하고 있습니다)

이에 맞춰 src/test/java 의 service 패키지도 com.boardproject.jpashop 내부로 옮겨주세요!
image

그리고 사용하지 않는 MemberRepository 는 헷갈릴 수 있으니 지워주십쇼!(아마도 메인 클래스와 같은 위치에 존재하는 MemberRepository를 지워주시면 될 것 같습니다!)

image

그 후에 테스트를 돌리시면

image이렇게 중복회원예외 테스트 코드에서 실패하게 됩니다.

예외 메시지를 읽어보니 IllegalAccessError가 발생해야 하는데 발생하지 않았다고 합니다.

MemberService 의 join 메서드를 가보겠습니다!

imageIllegalAccessErrror가 아니라 IllegalAccessException이 발생해야 합니다 :)

중복회원예외의 테스트 코드에서는

image이렇게 IllegalAccessError 가 오기를 기다리고 있습니다!

이걸 MemberService Join에 있는 예외 클래스인 IllegalAccessException 으로 변경해보겠습니다!

image다시 테스트를 돌려보겠습니다!

image동일한 예외가 발생합니다! ... 앗! 실패 메시지를 잘 읽어보니 예외가 발생하지 않았다고 합니다!

위의 테스트 코드를 보니 member2.setName() 하는 부분이 없습니다! 테스트 코드를 변경해주겠습니다!

image

다시 테스트를 돌려보면!(제발)

image이렇게 성공하게 됩니다!

감사합니다 :)

0

안녕하세요. 정윤영님, 공식 서포터즈 y2gcoder입니다.

아마도 질문 본문의 에러는 @SpringBootApplication 이 붙은 클래스를 찾지 못해 발생하는 에러 같습니다.

보통 이런 문제는 패키지와 관련이 있기 때문에 @SpringBootApplication 이 붙은 메인 클래스가 위치한 패키지 속에 해당 MemberService나 MemberRepository 클래스를 만들었는지 확인해보셔야 합니다!

밑의 댓글에 참고해주신 에러는 위의 에러를 해결하고 나서 확인해봐야 할 것 같습니다!

혼자서 해결하기 어렵다고 판단되실 경우에는

실제 동작하는 전체 프로젝트를 압축해서 구글 드라이브로 공유해서 링크를 남겨주세요.

구글 드라이브 업로드 방법은 다음을 참고해주세요.

https://bit.ly/3fX6ygx


주의: 업로드시 링크에 있는 권한 문제 꼭 확인해주세요


추가로 다음 내용도 코멘트 부탁드립니다.

1. 문제 영역을 실행할 수 있는 방법

2. 문제가 어떻게 나타나는지에 대한 상세한 설명


링크: 공식 서포터즈

링크: 자주하는 질문

감사합니다.

0

정윤영님의 프로필 이미지
정윤영
질문자

package com.boardproject.service;

import com.boardproject.jpashop.domain.Member;
import com.boardproject.repository.MemberRepository;
import com.boardproject.service.MemberService;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.Extension;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.transaction.annotation.Transactional;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
@Transactional // pk값이 같으면 같은 영속성으로 관리한다.
public class MemberServiceTest {

    @Autowired MemberService memberService;
    @Autowired MemberRepository memberRepository;


    @Test
    public void 회원가입() throws Exception{
        //given
        Member member = new Member();
        member.setName("jeong");

        //when
        Long savedId = memberService.join(member);

        //then
        assertEquals(member, memberRepository.findOne(savedId));
    }

    @Test
    public void 중복회원예외() throws Exception{
        //given
        Member member1 = new Member();
        member1.setName("jeong");

        Member member2 = new Member();
        member1.setName("jeong");

        //when
        memberService.join(member1);
        assertThrows(IllegalAccessError.class, () -> memberService.join(member2));

        //then
    }


}

 

 

두번째 질문입니다. MemberService 예외처리할때 영상을 그대로 따라하니까 에러 뜨는데, 이렇게 작성해도 맞는지 확인 부탁드립니다.

package com.boardproject.service;

import com.boardproject.jpashop.domain.Member;
import com.boardproject.repository.MemberRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;


@Service
@Transactional(readOnly = true) // JPA가 조회할때 최적화한다, 읽기엔 이거 넣는게 좋다
@RequiredArgsConstructor //final 가진 애들의 생성자를 자동 생성해준다
public class MemberService {


    private final MemberRepository memberRepository; //컴파일 시점에 값세팅 확인할수 있어 final 설정


    //회원 가입
    @Transactional //읽기가 아니라서 readonly 무시하기 위해 썼음
    public Long join(Member member) throws IllegalAccessException {
        validaateDuplicateMember(member); //중복회원 검증
        memberRepository.save(member);
        return member.getId();
    }


    private void validaateDuplicateMember(Member member) throws IllegalAccessException {
        //Exception
        List<Member> findMembers = memberRepository.findByName(member.getName());
        if(!findMembers.isEmpty()){
             throw new IllegalAccessException("이미 존재하는 회원입니다");

        }

    }

    //회원 전체 조회
    public List<Member> findMembers(){
        return  memberRepository.findAll();
    }

    public Member findOne(Long id){
        return memberRepository.findOne(id);
    }
}

 

0

안녕하세요, 인프런 AI 인턴입니다.

정윤영 님의 질문은 SpringBootTest 관련 에러와 관련된 것으로 보입니다. MemberServiceTest 실행 중 “Unable to find a @SpringBootConfiguration” 관련 오류가 발생하는 상황입니다. 이는 보통 테스트 코드에서 스프링 부트의 설정 파일(@SpringBootConfiguration)을 찾지 못할 때 발생합니다.

질문과 유사한 상황을 처리하는 기존 토론을 찾기 위해 노력했습니다. 아래는 이 문제와 관련된 기존 토론입니다:

이러한 문제는 일반적으로 다음과 같은 방법으로 해결할 수 있습니다:
1. 테스트 클래스에 @SpringBootTest 어노테이션을 추가합니다.
2. @SpringBootTest에 classes 속성을 사용하여 설정 클래스를 지정합니다.
3. @ContextConfiguration을 사용하여 구체적인 설정 클래스를 지정합니다.
4. @RunWith(SpringRunner.class) 또는 JUnit5일 경우 @ExtendWith(SpringExtension.class)를 사용하여 스프링의 테스트 컨텍스트를 로드합니다.

기존의 에러와 유사한 경우들을 참조하여 해결해 보시는 것이 좋을 것 같습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

정윤영님의 프로필 이미지
정윤영

작성한 질문수

질문하기