使用@Autowired为Spring @Service添加JUnit测试

时间:2017-09-27 08:30:16

标签: java spring web-services junit dozer

我已经检查了有关此主题的所有其他帖子和博客/维基,但我们的项目设置仍然存在问题。

项目ParentProject,有多个子项目。对于此特定问题,我们会考虑APIWS

Service中声明了一个界面@WebService(注释为@SOAPBindingAPI),其实现位于WS(注释为@WebService@Service)。

当尝试为此实现实现JUnit测试时,出于某种原因,maven clean install(在Eclipse中)以 BUILD FAILURE

结尾

遇到的一些问题:

Could not find an 'annotation declaring class' for annotation type [interface org.springframework.test.context.ActiveProfiles] and class [class com.x.ws.services.x.ServiceTest]
java.lang.NullPointerException
...
After test class: context [[TestContext@c0843d testClass = ServiceImplTest, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [MergedContextConfiguration@2e0dcb testClass = ServiceImplTest, locations = '{classpath:spring-config-business-test.xml}', classes = '{}', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader']]], dirtiesContext [false].
java.lang.NullPointerException
...
Caught exception while allowing TestExecutionListener 
[org.springframework.test.context.support.DependencyInjectionTestExecutionListener@1bcdc8] to prepare test instance [com.x.ws.services.x.ServiceImplTest@5d285b]
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.x.ws.services.x.ServiceImplTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.x.api.services.x.Service com.x.ws.services.x.ServiceImplTest.service; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.x.api.services.x.Service] 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)}

这是当前的 ServiceImplTest

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(
        locations = {
//                "classpath:spring-config-business.xml",
//                "classpath:spring-config-business-cxf.xml",
//                "classpath:dozer-config.xml"//,
                "classpath:spring-config-business-test.xml"
        })
//        classes = Service.class)
//@ComponentScan("com.<service_package>")
//@TestExecutionListeners({
    //org.springframework.test.context.support.DependencyInjectionTestExecutionListener.class,
    //org.springframework.test.context.support.DirtiesContextTestExecutionListener.class,
    //org.springframework.test.context.transaction.TransactionalTestExecutionListener.class
    })
//@Profile("test")
public class ServiceImplTest {

    @Autowired
    private Service service;
...
}

这是 spring-config-business-test.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
>

    <!-- Allow @Autowired Annotation -->
    <context:annotation-config/>

    <context:component-scan base-package="com.x.api"></context:component-scan>    
    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.SingleConnectionDataSource"
        p:driverClassName="${jdbcDriverDB2.className}"
        p:url="${testDataSource.url}"
        p:username="${testDataSource.user}"
        p:password="${testDataSource.password}"
        p:suppressClose="true" />

</beans>

使用 @Autowired 时无效,并且在不使用时会编译。

更新:

在调查并遵循评论中的说明后,我发现该日志显示多个 java.lang.NullPointerException ,在这些消息之后(针对另一个bean):

Creating shared instance of singleton bean 'x'
...
Processing injected method of bean 'x': AutowiredFieldElement for private package.ws.y package.ws.y.x

@Autowired只要ApplicationContext私有字段(无论是哪一个,甚至 ServiceImplTest ),测试也无法编译

Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@1c1fbd9] to prepare test instance [package.ws.services.x.ServiceImplTest@16f2b7f]
java.lang.IllegalStateException: Failed to load ApplicationContext

UPDATE2:

我尝试了@Louis Steimberg提到的(没有定义加载器),现在我得到了

testFunction(package.ws.services.x.ServiceImplTest): Error creating bean with name 'packge.ws.services.x.ServiceImplTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private package.ws.services.x.ServiceTest package.ws.services.x.ServiceImplTest.serviceTest; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [package.ws.services.x.ServiceTest] 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)}

看起来它出于某种原因无法创建bean。

1 个答案:

答案 0 :(得分:0)

您应该将此参数添加到@ContextConfiguration批注:

@ContextConfiguration(
    classes = {TestConfig.class },
    loader = AnnotationConfigWebContextLoader.class
    )

并在TestConfig.class中:

@Configuration
@ComponentScan(basePackages = "com.your.component.package1, com.your.component.package2")
public class TestConfig {

// You can put some beans here

}