2014-06-10 5 views
-1

JavaFX (저는 스프링 채널 MVC를 사용하여 가 아니요입니다)를 사용하여 스프링 어플리케이션을 개발하고 있으며 컨트롤러 - 서비스 - DAO와의 표준 분리 사항을 가지고 있습니다. JdbcTemplate을 사용하고 있습니다. 나는 내 서비스 중 하나에 대해 jUnit 테스트를 기꺼이 적어두기를 원한다. 구체적인 것은 서비스가 두 개의 DAO를 autowiring하고 (그 중 하나는 트랜잭션 자체를 사용함), 게다가 하나의 메소드 인 @Transactional이 있다는 것입니다.JUnit 테스트에서 중첩 된 autowiring이 작동하지 않습니다.

package org.impactvolunteers.management.service.impl; 

imports ...; 

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { "classpath:testContext.xml" }) 
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) 
public class RegisterVolunteerServiceImplTest extends 
     AbstractRegisterVolunteerServiceTest { 
    @Autowired 
    private RegisterVolunteerService registerVolunteerService; 

    @Before 
    public void setUp() { 
     setRegisterVolunteerService(registerVolunteerService); 
    } 

} 

그리고 내 서비스 구현 :

package org.impactvolunteers.management.service.impl; 

imports ...; 

public class RegisterVolunteerServiceImpl implements RegisterVolunteerService { 
    @Autowired 
    private VolunteerDao volunteerDao; 

    @Autowired 
    private UserDao userDao; 

    @Transactional(rollbackFor = { ServiceException.class, 
      ValidationException.class }) 
    public Volunteer registerVolunteer(User user, Volunteer volunteer) 
      throws ServiceException, ValidationException { 
     UserValidator.validateData(user); 
     VolunteerValidator.validateData(volunteer); 
     try { 
      User ret = userDao.create(user); 
      volunteer.setUser(ret); 
      return volunteerDao.create(volunteer); 
     } catch (PersistenceException e) { 
      throw new ServiceException(e.getMessage(), e); 
     } 
    } 
} 

그리고 애플리케이션 컨텍스트에서을 :

: 여기
<context:component-scan base-package="org.impactvolunteers.management"/> 

    <!-- enable the configuration of transactional behavior based on annotations --> 
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/> 

    <!-- Transaction Manager --> 
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
     <property name="dataSource" ref="dataSource"/> 
    </bean> 

    ... 
    <bean id="registerVolunteerService" class="org.impactvolunteers.management.service.impl.RegisterVolunteerServiceImpl" > 
    </bean> 

오류 메시지입니다 이건 내 테스트가 정확히 모습입니다

org.springframework.beans.factory.BeanCreationException : 오류 'org.impactvolunteers.management.service.impl.RegisterVolunteerServiceImplTest': 자동 빌드 된 종속성의 주입에 실패했습니다. 상자의 예외는 org.springframework.beans.factory.BeanCreationException입니다 : 수 없습니다 자동으로 묶어 필드 : 개인 org.impactvolunteers.management.service.RegisterVolunteerService org.impactvolunteers.management.service.impl.RegisterVolunteerServiceImplTest.registerVolunteerService; 중첩 예외 org.springframework.beans.factory.NoSuchBeanDefinitionException이다 된 타입의 적격 콩 [org.impactvolunteers.management.service.RegisterVolunteerService] 의존성 발견위한 자동으로 묶어 후보 자격 예상 적어도 1 콩 이 종속성. 종속성 주석 : {@ org.springframework.beans.factory.annotation.Autowired가 (필수 = TRUE)} org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues ​​(AutowiredAnnotationBeanPostProcessor.java:288) 에서 .... org.springframework.beans.factory.NoSuchBeanDefinitionException : ........ 에 의한 것으로, 적어도 1 빈 : 된 타입의 적격 빈이 [org.impactvolunteers.management.service.RegisterVolunteerService] 의존성 발견 이 종속성에 대해 autowire 후보로 자격이 부여됩니다. 종속성 주석 : {org.springframework.beans.factory.annotation.Autowired @ (필수 = TRUE)} org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException (DefaultListableBeanFactory.java:988)에서 org.springframework에서 .beans.factory.support.DefaultListableBeanFactory.doResolveDependency (DefaultListableBeanFactory.java:858) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency (DefaultListableBeanFactory.java:770) at org.springframework.beans.factory.annotation .AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject (AutowiredAnnotationBeanPostProcessor.java:486) ... 28 더

그리고 내 test-Context.XML은 :

<context:annotation-config/> 

    <context:component-scan base-package="org.impactvolunteers.management"/> 

    <bean id="jdbc" class="org.springframework.jdbc.core.JdbcTemplate"> 
     <property name="dataSource" ref="dataSource"/> 
    </bean> 

    <!-- Spring JDBC Utility for in-memory database --> 
    <jdbc:embedded-database id="dataSource" type="HSQL"/> 

두 이상한 일들이 내가주의 :

  1. 나는 Java 응용 프로그램과 응용 프로그램을 시작 아무 문제가 의도 한대로 서비스가 작동합니다. 나는 서비스를 jUnit 테스트로 테스트하는 데 문제가있다.
  2. 정확하게 동일한 컨텍스트 (테스트와 동일한 테스트 컨텍스트가 여기에 표시됨)와 bean 정의가 @Transactional 주석이 포함되어 있지 않은 유일한 차이점을 사용하여 성공적으로 테스트되고 있습니다. 여기에 일부 DAO가 있습니다 do (VolunteerDaoImpl에는 VolunteerDao@Transactional 주석이 포함되어 있음).
+1

클래스 RegisterVolunteerServiceImpl이 서비스로 주석을해야하지 않고 콩을 추가합니다. – Jens

+1

네, 효과가있었습니다. 이 사건에 왜 그런지 설명해 주시겠습니까? –

+0

예 답변을 작성하겠습니다. 귀하를위한 해결책 인 경우이를 수락 할 수 있습니다. – Jens

답변

2

클래스 RegisterVolunteerServiceImpl은 서비스로 주석되어야합니다.

클래스가 서비스로 주석 처리되지 않은 경우 요소 스캔에 의해 발견되지 않습니다. 따라서 이름이있는 bean은 인스턴스화되지 않고 autowire 될 수 없습니다. 주요 응용 문맥에서

당신은 구성 요소 스캔

<bean id="registerVolunteerService" class="org.impactvolunteers.management.service.impl.RegisterVolunteerServiceImpl" > 
    </bean> 
+0

일반적인 Java 응용 프로그램처럼 응용 프로그램을 시작할 때 서비스가 어떻게 발견되는지 설명 할 수 있습니까? 그리고 왜 다른 서비스가 서비스로 주석이 달려 있지 않은 테스트 케이스에서 발견되고 있습니까? –

+0

@IvayloToskov 내 게시물을 업데이트했습니다. – Jens

+0

완전한 테스트 컨텍스트가 있으면 안되며, 다를 필요가 있거나 추가되어야하는 bean 만 재정의해야합니다. 다음으로 일반적인 컨텍스트 파일과 수정 된 테스트 컨텍스트 (아마도'DataSource'와 아마'JdbcTemplate' 만 포함해야합니다)를 모두로드하십시오. –

1

해당 testContext.xml은 일반 용도의 응용 프로그램 컨텍스트를 가져 오지 않으며 해당 registerVolunteerService bean을 정의하지 않습니다.

+0

서비스 주석을 추가하면 문제가 발생하지 않았고 다른 테스트 사례는 의도 한대로 작동했습니다. –

+0

그게 바로 * 다른 문제 (구성 요소 스캐닝, 이번에는)에서 콩을 만드는 Spring을 가지고 있기 때문에 * 정확하게 * 문제였습니다. 따라서 일반 XML 컨텍스트에서 빈 선언을 제거 할 수도 있습니다. – chrylis

+1

나는 지금 이해할 것 같아. 일반적인 응용 프로그램으로 시작하는 동안 발견되는 이유는 bean으로 applicationContext에 정의되어 있지만 jUnit 테스트로 시작할 때 검사해야하지만 @Service 주석이 없으면 그렇지 않습니다. 발견 되니? 맞다면 나에게 남겨진 질문은 테스트 중에 다른 주석이 달린 서비스가 발견되지 않는 이유입니다.하지만이 특별한 질문은 아닙니다. 제가 말한 것처럼 일반적인 차이점은이 서비스에는 트랜잭션 방식이 있다는 것입니다. –

관련 문제