在运行测试时在Spring MVC中注入Bean。

huangapple go评论63阅读模式
英文:

injecting beans in Spring MvC when running a test

问题

当我运行一个测试时,出现了这个错误:

嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:找不到符合条件的类型为 'com.bonanza.api.IWorkflowService' 的 bean:预期至少有1个符合自动装配候选的 bean。依赖注释:{@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>
英文:

I have this error when I run a test:

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

and this is the servlet-xml I load when running the classes:

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

答案1

得分: 0

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

为了解决这个问题,你有几个选项。

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

另一方面,你可以为该接口提供一个模拟对象。你可以使用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());
    }
}
英文:

I think your problem is that you are trying to use an interface instead of a concrete class to inject the dependency of type com.bonanza.api.IWorkflowService required other beans in your application.

In order to solve the problem, you have several options.

On one hand, you can of course provide an actual implementation for that interface.

Or, on the other hand, you can provide a mock object for that interface. You can use Mockito for that, and modify your Spring XML configuration with something similar to the following code:

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

If required, you can customize the mock behavior in your configuration (from your other question):

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(&quot;classpath:backoffice-servlet.xml&quot;)
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(&quot;/time/2&quot;)
                .contentType(APPLICATION_JSON))
                .andExpect(status().isOk());
    }
}

huangapple
  • 本文由 发表于 2020年10月5日 06:15:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/64200398.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定