如何测试自己具有自动装配依赖关系的 Spring 服务 bean?
Posted
技术标签:
【中文标题】如何测试自己具有自动装配依赖关系的 Spring 服务 bean?【英文标题】:How to test Spring service beans that themself have autowired dependencies? 【发布时间】:2014-06-22 18:09:37 【问题描述】:我想测试一些他们自己包含其他自动装配服务的服务。但是测试本身不需要这些“外部”服务。
如何创建测试设置,例如以下示例?
package de.myapp.service;
@Service
public class MyServiceDelegator
@Autowired
private List<ServiceInterface> services;
public ServiceInterface delegate(String id)
//routine to find the right ServiceInterface based on the given id
@Service
public class MyService implements ServiceInterface
@Service
public class MyCustomService implements ServiceInterface
//that is the problem during testing
@Autowired
private de.myapp.repository.SomeDao dao;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("applicationContext.xml")
public class ServiceDelegatorTest
@Autowired
private ApplicationContext ac
@Test
public void testDelegator()
MyServiceDelegator dg = ac.getBean(MyServiceDelegator.class);
ac.delegate("test");
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="de.myapp.service" />
</beans>
问题:所有包含来自未在JUnit
测试中扫描的包的自动装配依赖项的服务(如MyCustomService
)都会抛出异常:
原因: org.springframework.beans.factory.NoSuchBeanDefinitionException: 否 为依赖找到了类型为 [SomeDao] 的合格 bean:预计在 至少 1 个有资格作为自动装配候选者的 bean 依赖。依赖注解: @org.springframework.beans.factory.annotation.Autowired(required=true) 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1103) 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:963) 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858) 在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480) ... 57 更多
【问题讨论】:
你在使用SpringJUnit4ClassRunner
吗?
是的,见上面的@RunWith(SpringJUnit4ClassRunner.class)
啊,不好意思,同班一起跑,错过了。
通常的方法是创建一个application-text.xml
来定义测试所需的额外bean。由于某种原因这不可行吗?
【参考方案1】:
您可以使用Springockito 将模拟服务实现添加到您的测试应用程序上下文中。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mockito="http://www.mockito.org/spring/mockito"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"
http://www.mockito.org/spring/mockito
http://www.mockito.org/spring/mockito.xsd">
<context:component-scan base-package="de.myapp.service" />
<mockito:mock id="dao" class="de.myapp.repository.SomeDao" />
</beans>
【讨论】:
这是一个完美的框架!是否也可以用它来模拟@Value
注解?【参考方案2】:
问题在于SomeDao
没有被组件扫描拾取,因为它不在de.myapp.service
包下。
您已经明确声明组件扫描的包是de.myapp.service
。
我建议您进行以下更改:
<context:component-scan base-package="de.myapp" />
这样de.myapp
下的所有代码都可以进行组件扫描。
如果您想避免在组件扫描中包含所有代码,您可以执行以下操作:
<context:component-scan base-package="de.myapp.service, de.myapp.repository" />
【讨论】:
我试图避免扩展包扫描,因为SomeDao
本身将包含另一个注入的依赖项,该依赖项具有另一个依赖项,该依赖项具有另一个依赖项,可能具有仅在网络服务器应用程序上下文(如 ContextCloseListener
或类似名称)。我不认为扫描我的整个应用程序是测试单个需求的好解决方案...
是的,谢谢,但问题仍然存在,因为存储库 bean 在这里也只是一个示例:任何 bean 都可能包含当前扫描上下文之外的任何其他 bean。所以我必须添加所有的 spring 服务,这很困难,因为其中一些将依赖于 webserver、数据库配置等。
我明白你的意思。但是如果你想要真正的集成测试,你必须以某种方式包含依赖bean。这将使用组件扫描、XML 或 Java Config(可能与 Spring Profiles 一起)来完成以上是关于如何测试自己具有自动装配依赖关系的 Spring 服务 bean?的主要内容,如果未能解决你的问题,请参考以下文章
Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.4.5 自动装配