英文:
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 '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)}
and this is the servlet-xml I load when running the classes:
<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>
答案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:
<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>
If required, you can customize the mock behavior in your configuration (from your other question):
@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());
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论