작성
·
945
·
수정됨
0
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class ReviewGetService {
private final ReviewRepository reviewRepository;
private final ReviewValidService reviewValidService;
private final ReviewMapper mapper;
}
@Service
@Transactional
@RequiredArgsConstructor
public class ReviewService {
private final ReviewRepository reviewRepository;
private final ReviewValidService reviewValidService;
private final FileUploader fileUploader;
}
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class ReviewValidService {
private final ReviewRepository reviewRepository;
}
----Repository----
@Repository
public interface ReviewJpaRepository extends JpaRepository<Review,Long>,ReviewRepository {
}
public interface ReviewRepository {
}
----Controller----
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class ReviewController {
private final ReviewGetService getService;
private final ReviewService service;
}
제가 작성한 코드에서 의존성을 주입 받는 것들입니다.
실제로 실행 시 정상적으로 작동을 하는데 Test만 돌리면 Bean 등록에 실패했다는 문구가 나옵니다.
다른 부분은 문제가 없어보이고 ReviewGetService에서 Bean 등록 실패가 발생합니다.
아래는 예외 발생한 문구 입니다.
2023-06-14 02:04:52.885 WARN 97966 --- [ Test worker] o.s.w.c.s.GenericWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'reviewController' defined in file [/Users/siglee/Desktop/study/project/semi_project/devstore/BE/backend/build/classes/java/main/project/main/webstore/domain/review/controller/ReviewController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'reviewGetService' defined in file [/Users/siglee/Desktop/study/project/semi_project/devstore/BE/backend/build/classes/java/main/project/main/webstore/domain/review/service/ReviewGetService.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'project.main.webstore.domain.review.repository.ReviewRepository' available: expected single matching bean but found 2: reviewJpaRepository,project.main.webstore.domain.review.repository.ReviewRepository#0
Description:
Parameter 0 of constructor in project.main.webstore.domain.review.service.ReviewGetService required a single bean, but 2 were found:
- reviewJpaRepository: defined in project.main.webstore.domain.review.repository.ReviewJpaRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration
- project.main.webstore.domain.review.repository.ReviewRepository#0: defined in unknown location
Action:
Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type 'project.main.webstore.domain.review.repository.ReviewRepository' available:
expected single matching bean but found 2:
reviewJpaRepository,project.main.webstore.domain.review.repository.ReviewRepository#0
ReviewGetService 빈을 등록할 때 repository에 매핑될 빈이 1개여야하는데 2개라서 문제가 발생한 것이다. 라는 의미인 것 같습니다.
@SpringBootTest
class WebstoreApplicationTests {
@Test
void contextLoads() {
}
}
에서 테스트 진행 시에는 또 잘 작동합니다.
다만 제가 테스트를 위해 만든 클래스들에서 @SpringBootTest 어노테이션을 이용해서 작업 시 모두 ReviewGetService 빈 등록 시 Repository때문에 문제가 발생한다 라는 문구가 발생합니다.
질문 1. 동일한 의존성을 가지는 ReviewService에서는 왜 이런 문제가 발생하지 않는 것인가?
질문 2. 이럴 경우 직접 Bean을 등록해줘야되는 것인가? 다른 해결 방법은 없는 것인가
입니다.
답변 1
0
안녕하세요, 인프런 AI 인턴입니다.
Test에서만 Bean 등록 실패 문제가 발생한다면 해당 클래스가 Test 환경에서 필요한 bean을 찾지 못하고 있는 것 같습니다. 이런 경우에는 Test 환경에서 해당 bean을 등록해주는 작업이 필요합니다.
해당 문제를 해결하기 위해서는 ReviewGetService 클래스가 필요로 하는 bean을 Test 환경에서도 등록해주어야 합니다. 이를 위해 @Mock, @Autowired 등을 사용하여 필요한 bean을 등록하는 것이 일반적입니다. 이전 버전의 Spring에서는 @RunWith(MockitoJUnitRunner.class)과 @Mock을 사용하였으나, 현재는 @ExtendWith(MockitoExtension.class)와 @MockBean이 사용되고 있습니다.
참고로 @Mock은 가짜 객체(mock object)를 생성하는 애노테이션으로, 주입한 가짜 객체는 실제 객체처럼 구현되어 있어서 테스트 용도로 사용됩니다. @MockBean은 존재하는 빈(bean)을 대체하여 사용하는 애노테이션입니다.
해당 문제를 해결하기 위해서는 Test 코드에서 ReviewGetService가 필요로 하는 bean들을 등록해 주어야 하며, 이를 위해서는 @Mock, @Autowired, @ExtendWith, @MockBean 등을 활용하여 구현하면 됩니다.
동작하지 않는 코드를 보고 원인 파악과 해결을 할 수 없으므로, 자세한 코드와 에러 메시지를 함께 알려주시면 보다 정확한 도움을 드릴 수 있습니다. 감사합니다.