我的问题类似于this one。
设置 :
我有GreetingResource
Autowired
GreetingService
来处理GET
次请求:
@Path("greetings")
public class GreetingResource
{
@Autowired
private GreetingService service;
@GET
@Produces(MediaType.TEXT_PLAIN_VALUE)
public String getHello()
{
try
{
return service.greet("world");
}
catch(SQLException e)
{
System.out.println("Request failed (500)");
e.printStackTrace();
return null;
}
}
}
问题 :在我的单元测试中,我得到了 org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type 'demo.rest.jersey.spring.GreetingService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1466)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1097)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1059)
at org.glassfish.jersey.server.spring.AutowiredInjectResolver.getBeanFromSpringContext(AutowiredInjectResolver.java:104)
at org.glassfish.jersey.server.spring.AutowiredInjectResolver.resolve(AutowiredInjectResolver.java:96)
单元测试类 :为了对单元测试进行单元测试,我有testContext.xml
作为单元测试的应用程序上下文。它只创建一个bean,即TestConfig
:
@Configuration
public class TestConfig
{
@Bean
@Primary
public GreetingService greetingService() throws SQLException
{
GreetingService service = Mockito.mock(GreetingService.class);
when(service.greet(anyString())).thenReturn("Hello");
return service;
}
}
testContext.xml
应该由单元测试加载,因此创建了正确的bean:
public class Test_GreetingResource extends JerseyTest
{
@Override
protected TestContainerFactory getTestContainerFactory()
{
return new GrizzlyWebTestContainerFactory();
}
@Override
protected DeploymentContext configureDeployment(){
return ServletDeploymentContext
.forServlet(new ServletContainer(new TestApp()))
.addListener(ContextLoaderListener.class)
.contextParam("contextConfigLocation", "classpath:testContext.xml")
.build();
}
@Test
public void doTest() throws SQLException
{
String response = target("greetings").request().get(String.class);
assertEquals("response incorrect", "Hello", response);
System.out.println(response);
}
}
备注 :TestApp
只是注册GreetingResource
public class TestApp extends ResourceConfig
{
public TestApp()
{
register(GreetingResource.class);
packages("demo.rest.jersey.spring");
}
}
以下是我上面提到的testContext.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<bean id="testConfig" class="demo.rest.jersey.spring.TestConfig"></bean>
</beans>
其他问题 :如果将GreetingService
模拟创建为bean,我可以以某种方式改变模拟行为吗?即现在我在TestConfig
中指定模拟应该给出的响应,但我可能想要改变从测试到测试的行为。
感谢您的帮助!
答案 0 :(得分:0)
我关注this answer并将GreetingService
注入GreetingResource
的构造函数中。
然后就是
public class Test_GreetingResource extends JerseyTest
{
@Mock
private GreetingService service;
@Override
public ResourceConfig configure()
{
MockitoAnnotations.initMocks(this);
return new ResourceConfig()
.register(new GreetingResource(service));
}
@Test
public void testMockedGreetingService()
{
try {
when(service.greet(anyString())).thenReturn("Hello there");
} catch (SQLException e) {
fail("service cannot greet");
}
Response response = target("greetings")
.request(MediaType.TEXT_PLAIN).get();
String msg = response.readEntity(String.class);
System.out.println("Message: " + msg);
response.close();
}
}