【问题标题】:Spring unit test objects autowired with null fields使用空字段自动装配的 Spring 单元测试对象
【发布时间】:2015-09-11 19:47:24
【问题描述】:

我正在尝试在我的 spring servlet 中为休息服务创建单元测试。但是当控制器对象由@autowire 创建时,它的所有@autowired 字段都是空的。

我的测试类如下,使用 SpringJUnit 运行器和上下文配置集

@ContextConfiguration(locations = "ExampleRestControllerTest-context.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class ExampleRestControllerTest {

    @Autowired
    private BaseService mockExampleService;

    @Autowired
    private ExampleRestController testExampleRestController;

ExampleRestControllerTest-context.xml 设置要模拟的服务并将模拟对象注入控制器

<context:annotation-config/>

<import resource="classpath*:example-servlet.xml"/>

<bean id="mockExampleService" class="org.easymock.EasyMock" factory-method="createMock">
    <constructor-arg index="0" value="za.co.myexample.example.services.BaseService"/>
</bean>
<bean id="testExampleRestController" class="za.co.myexample.example.rest.controller.ExampleRestController">
    <property name="exampleService" ref="mockExampleService"/>
</bean>

控制器使用的其余 bean 定义在 example-servlet.xml 中

<bean id="RESTCodeMapper" class="za.co.myexample.example.rest.util.RESTCodeMapper"/>

<bean id="restProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
        <property name="location" value="classpath:RESTServiceCodeMapping.properties"/>
</bean>

连同我的 Jax2BMarshaller。

我的 IDE 可以很好地链接到这些定义,如果我删除任何定义,我会得到预期的“无合格 bean”错误。

我的问题是,当我运行单元测试时,提供的控制器的所有字段都为空

@Controller
public abstract class BaseRestController {

    private static Logger LOGGER = Logger.getLogger(BaseRestController.class);
    protected final String HEADERS = "Content-Type=application/json,application/xml";
    @Autowired
    protected RESTCodeMapper restCodeMapper;

    @Autowired
    protected BaseService exampleService;

    @Autowired
    protected Jaxb2Marshaller jaxb2Marshaller;

(及其实现类)

@Controller
@RequestMapping("/example")
public class ExampleRestController extends BaseRestController {

当我在我的 Weblogic 服务器中运行正确的代码时,字段会正确填充。更重要的是,如果我直接在我的测试类中添加这些字段,这些字段也会正确地得到@autowired。因此,我可以在我的测试类中 @autowire 这些对象,然后将它们直接设置到我的控制器中。但这不是正确的做法。

所以问题是,当我的测试类直接在同一个测试类中自动装配这些对象时,或者如果我在我的 Weblogic 服务器上正常运行代码时,为什么我的测试类中自动装配对象的自动装配字段为空。

【问题讨论】:

    标签: java spring junit


    【解决方案1】:

    在您的测试类中,@Autowired 对象由于上下文配置而为空,因此将其更改为:

    @ContextConfiguration(locations = "ExampleRestControllerTest-context.xml")
    

    @ContextConfiguration(locations = "classpath:/ExampleRestControllerTest-context.xml")
    

    ExampleRestControllerTest

    所以问题是,为什么自动装配的自动装配字段 我的测试类中的对象 null 当它直接自动连接这些对象时 在同一个测试类中,或者如果我在我的 Weblogic 上正常运行代码 服务器。

    它们在自动装配对象的构造函数中必须为空。您可以尝试在 autowired 对象中创建 @PostConstruct 方法,并且在此方法中 autowired 对象不能为 null

    【讨论】:

    • 将 ContextConfiguration 更改为仍然具有完全相同的效果。 ExampleRestController 是通过@Autowire 创建的,但它的字段是由@Autowired protected RESTCodeMapper restCodeMapper; @Autowired protected BaseService exampleService; @Autowired protected Jaxb2Marshaller jaxb2Marshaller; 创建的,BaseRestController 使用带有服务设置器的默认构造函数,因此可以注入它。
    • 这个问题是由于bean初始化顺序不正确造成的。 ExampleRestControllerTest-context.xml 中定义的 bean 在 example-servlet.xml 中的 bean 之前初始化。尝试在调用 autowired beans 之前在 ExampleRestControllerTest 中添加 SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
    • 我尝试按照您的建议将SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this); 添加到ExampleRestControllerTest,我还尝试了SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(testExampleRestController); 并在控制器本身内尝试了SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);。我尝试删除导入并将 bean 移动到 context.xml,以便在控制器之前初始化 bean。所有这些事情仍然有完全相同的结果;控制器的字段中仍有空值
    • 我同意,如果 bean 没有在 spring 正确实例化,那应该可以工作。但我认为使用processInjectionBasedOnCurrentContext() 具有相同的效果并遇到相同的问题,因为Spring 出于某种原因将bean 实例化为null。或者至少我是这么认为的
    • yap,这真的很奇怪,因为我有非常相似的场景。我发现你的配置和我的配置之间还有一个不同之处。我不相信它会解决问题,但你可以试试。您的配置文件中缺少&lt;context:component-scan&gt; 标签。 This答案可能会更好地解释它
    猜你喜欢
    • 2016-03-29
    • 2013-07-11
    • 2011-11-20
    • 2015-07-28
    • 1970-01-01
    • 1970-01-01
    • 2021-07-02
    • 2017-08-06
    • 1970-01-01
    相关资源
    最近更新 更多