在 运行 测试时在 Spring MvC 中注入 bean

injecting beans in Spring MvC when running a test

我在 运行 测试时遇到这个错误:

nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.bonanza.api.IWorkflowService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

这是 servlet-xml 我在 运行 加载 类 时加载:

  <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"
            xmlns:jpa="http://www.springframework.org/schema/data/jpa"
            xmlns:util="http://www.springframework.org/schema/util"
            xmlns:tx="http://www.springframework.org/schema/tx"
            xmlns:mvc="http://www.springframework.org/schema/mvc"
            xsi:schemaLocation="
            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/data/jpa
            http://www.springframework.org/schema/data/jpa/spring-jpa.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">
    
        <context:annotation-config />
        <context:component-scan base-package="com.bonanza.*" />
        <jpa:repositories base-package="com.bonanza.*" />
        <!-- transaction management -->
        <mvc:annotation-driven />
    
        <bean id="workflowService"
                class="com.bonanza.api.IWorkflowService" abstract="true"/>
..
</beans>

我认为你的问题是你试图使用一个接口而不是一个具体的 class 来注入类型 com.bonanza.api.IWorkflowService 的依赖项需要你的应用程序中的其他 bean。

为了解决问题,你有几种选择。

一方面,您当然可以提供该接口的实际实现。

或者,另一方面,您可以为该接口提供模拟对象。您可以为此使用 Mockito,并使用类似于以下代码的内容修改您的 Spring XML 配置:

<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"
            xmlns:jpa="http://www.springframework.org/schema/data/jpa"
            xmlns:util="http://www.springframework.org/schema/util"
            xmlns:tx="http://www.springframework.org/schema/tx"
            xmlns:mvc="http://www.springframework.org/schema/mvc"
            xsi:schemaLocation="
            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/data/jpa
            http://www.springframework.org/schema/data/jpa/spring-jpa.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">
    
        <context:annotation-config />
        <context:component-scan base-package="com.bonanza.*" />
        <jpa:repositories base-package="com.bonanza.*" />
        <!-- transaction management -->
        <mvc:annotation-driven />
    
        <bean id="workflowService" class="org.mockito.Mockito" factory-method="mock">
            <constructor-arg value="com.bonanza.api.IWorkflowService" />
        </bean>
..
</beans>

如果需要,您可以在配置中自定义模拟行为(来自您的):

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration("classpath:backoffice-servlet.xml")
public class TimeControllerTests {

    @Autowired
    private WebApplicationContext wac;

    @Autowired
    private IWorkflowService workflowService;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
        // given(this.workflowService...).willReturn(...);
    }
    
    @Test
    public void should_OK() throws Exception {

        mockMvc.perform(get("/time/2")
                .contentType(APPLICATION_JSON))
                .andExpect(status().isOk());
    }
}