2

Really need help. I used JUnit(4.6) plus Spring(3.0.5) for unit testing. When I tried to autowire a service object in my test class, I got a NoSuchBeanDefinitionException.

The JUnit code:

package com.aaa.service.impl;

@ContextConfiguration(locations = { "classpath:/spring/applicationContext.xml",
    "classpath:/spring/applicationContext-aop.xml",
    "classpath:/spring/applicationContext-dao.xml",
    "classpath:/spring/applicationContext-service.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
public class TestManageTargetServiceImpl {

    @Autowired
    ManageTargetServiceImpl manageTargetServiceImpl;

    @Test
    public void testQueryFinancialMonthList() {
        List<Map<String, Object>> value = new ArrayList<Map<String, Object>>();
        ManageTargetDao manageTargetDao = mock(ManageTargetDao.class);
        when(manageTargetDao.queryFinancialMonthList()).thenReturn(value);
        manageTargetServiceImpl.setManageTargetDao(manageTargetDao);
        // I hope it return null
        assertNull(manageTargetServiceImpl.queryFinancialMonthList());
    }
}

The applicationContext-service.xml code:

<context:annotation-config />

<bean id="manageTargetService" class="com.aaa.service.impl.ManageTargetServiceImpl">
    <property name="manageTargetDao" ref="manageTargetDao"></property>
</bean>

The error track:

00:51:28,625 ERROR main context.TestContextManager:324 - Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@882dfc] to prepare test instance [com.aaa.service.impl.TestManageTargetServiceImpl@ce2db0]
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.aaa.service.impl.TestManageTargetServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.aaa.service.impl.ManageTargetServiceImpl com.aaa.service.impl.TestManageTargetServiceImpl.manageTargetServiceImpl; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.aaa.service.impl.ManageTargetServiceImpl] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

Some log:

00:51:26,828 DEBUG main context.TestContextManager:282 - beforeTestClass(): class [class com.aaa.service.impl.TestManageTargetServiceImpl]
00:51:26,828 DEBUG main annotation.ProfileValueUtils:68 - Retrieved @ProfileValueSourceConfiguration [null] for test class [com.aaa.service.impl.TestManageTargetServiceImpl]
00:51:26,828 DEBUG main annotation.ProfileValueUtils:80 - Retrieved ProfileValueSource type [class org.springframework.test.annotation.SystemProfileValueSource] for class [com.aaa.service.impl.TestManageTargetServiceImpl]
00:51:26,828 DEBUG main context.TestContextManager:315 - prepareTestInstance(): instance [com.aaa.service.impl.TestManageTargetServiceImpl@ce2db0]
00:51:26,843 DEBUG main support.DependencyInjectionTestExecutionListener:73 - Performing dependency injection for test context [[TestContext@e0eb3f testClass = TestManageTargetServiceImpl, locations = array<String>['classpath:/spring/applicationContext.xml', 'classpath:/spring/applicationContext-aop.xml', 'classpath:/spring/applicationContext-dao.xml', 'classpath:/spring/applicationContext-service.xml'], testInstance = com.aaa.service.impl.TestManageTargetServiceImpl@ce2db0, testMethod = [null], testException = [null]]].
00:51:26,843 DEBUG main support.AbstractGenericContextLoader:75 - Loading ApplicationContext for locations [classpath:/spring/applicationContext.xml,classpath:/spring/applicationContext-aop.xml,classpath:/spring/applicationContext-dao.xml,classpath:/spring/applicationContext-service.xml].
00:51:26,968  INFO main xml.XmlBeanDefinitionReader:315 - Loading XML bean definitions from class path resource [spring/applicationContext.xml]
00:51:27,187  INFO main xml.XmlBeanDefinitionReader:315 - Loading XML bean definitions from class path resource [spring/applicationContext-aop.xml]
00:51:27,312  INFO main xml.XmlBeanDefinitionReader:315 - Loading XML bean definitions from class path resource [spring/applicationContext-dao.xml]
00:51:27,421  INFO main xml.XmlBeanDefinitionReader:315 - Loading XML bean definitions from class path resource [spring/applicationContext-service.xml]
00:51:27,453  INFO main support.GenericApplicationContext:456 - Refreshing org.springframework.context.support.GenericApplicationContext@16c14e7: startup date [Tue Jan 01 00:51:27 NZDT 2013]; root of context hierarchy
00:51:27,718  INFO main config.PropertyPlaceholderConfigurer:177 - Loading properties file from class path resource [jdbc.properties]
00:51:27,796  INFO main support.DefaultListableBeanFactory:555 - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@2938d8: defining beans [loggingAop,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.aop.aspectj.AspectJPointcutAdvisor#0,service,loginDao,manageTargetDao,org.springframework.beans.factory.config.PropertyPlaceholderConfigurer#0,dataSource,txManager,txAdvice,txDAO,org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,loginService,manageTargetService]; root of factory hierarchy
Albert
  • 53
  • 1
  • 6
  • Are you sure that there are no other errors in the stacktrace? Maybe manageTargetService can't be created in the container because of some errors etc. (Or becuase manageTargetDao not found - it must be available as it's specified as a property in your xml) – Boris Treukhov Dec 31 '12 at 13:53
  • 1
    Guessing here - but given that injection of a class type `ManageTargetServiceImpl` is failing, I think the reason is that a proxy is getting created for `ManageTargetServiceImpl` and so the type of the bean will not be `ManageTargetServiceImpl` anymore but the interface of that class. – Biju Kunjummen Dec 31 '12 at 14:53
  • Hi, Biju, you are correct, thank you. I added the aop method and declared transaction on the `ManageTargetServiceImpl`. And I just tried to remove the aops, the @Autowired works well. Thank you! @Biju Kunjummen – Albert Dec 31 '12 at 23:20

2 Answers2

0

Look at your property id. It should be manageTargetServiceImpl in your applicationContext-service.xml

Change it to this:

<bean id="manageTargetServiceImpl" class="com.aaa.service.impl.ManageTargetServiceImpl">
    <property name="manageTargetDao" ref="manageTargetDao"></property>
</bean>
Matin Kh
  • 5,192
  • 6
  • 53
  • 77
  • Hi, Matin, thank you for your reply. However, I changed the id, and it still doesn't work with the same exception. Moreover, I think the default auto wire type of @Autowired is byType. – Albert Dec 31 '12 at 13:06
  • Are you using several `applicationContext` files? Make sure they have access to each other using ` – Matin Kh Dec 31 '12 at 13:20
  • `@Autowired` ALWAYS uses by-type wiring. – Boris Treukhov Dec 31 '12 at 13:56
  • Hi, Matin, Boris, thanks for your help. The reason is I added aop on the `ManageTargetServiceImpl`, so its type of the bean in the Spring is `ManageTargetServiceImpl` 's interface `ManageTargetService`. – Albert Dec 31 '12 at 23:22
0

Guessing here - but given that injection of a class type ManageTargetServiceImpl is failing, I think the reason is that a proxy is getting created for ManageTargetServiceImpl and so the type of the bean will not be ManageTargetServiceImpl anymore but the interface of that class.

from Biju Kunjummen

  • Biju Kunjummen is correct. I added the aop method and declared transaction on the ManageTargetServiceImpl. After removing the aops, the @Autowired works well. – Albert Dec 31 '12 at 23:31