您的位置:首页 > 其它

Specified class is an interface

2016-10-25 08:34 1301 查看
使用mockmvc在controller做测试时遇到如下exception:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.domain.Pageable]: Specified class is an interface

at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:980)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:859)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844)
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:65)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:770)
at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:167)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:155)
at com.seewo.demo.web.controller.TestDemoController.should_return_demos_when_request_success(TestDemoController.java:105)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:254)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.domain.Pageable]: Specified class is an interface
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:101)
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.createAttribute(ModelAttributeMethodProcessor.java:137)
at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.createAttribute(ServletModelAttributeMethodProcessor.java:80)
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:106)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:99)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:817)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:731)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968)
... 38 more


分页接口无法实例化的问题

解决方案:

在测试类中加上如下成员变量:

@InjectMocks
private PageableHandlerMethodArgumentResolver pageableArgumentResolver;


然后在setup函数中调用:.setCustomArgumentResolvers(pageableArgumentResolver)

@Before
public void setup() {
//将打上Mockito标签的对象起作用,使得mock的类被mock,使用了mock对象的类自动与mock对象关联.
MockitoAnnotations.initMocks(this);
//这个对象时controler单元测试的关键,它的初始化也是在setup方法里面.
this.mockMvc = MockMvcBuilders.standaloneSetup(demoController).setCustomArgumentResolvers(pageableArgumentResolver).build();
}


完整的mockmvc测试controller层代码如下:

import com.seewo.demo.entity.Demo;
import com.seewo.demo.service.DemoService;
import com.seewo.demo.vo.query.DemoQuery;
import org.apache.log4j.Logger;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import java.util.ArrayList;
import java.util.List;

import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

/**
* 描述:测试
*
* @author yangshusheng
* @version v1.0
*/
//表示使用spring Test 组件进行单元测试
@RunWith(SpringJUnit4ClassRunner.class)
//使用这个annotate会在跑单元测试的时候真是的启动一个web服务,然后开始调用controller的rest Api,待单元测试跑完后再将web服务停掉.
@WebAppConfiguration
//指定bean的配置文件信息,可以有多种方,这个例子使用的是文件路径的形式,如果有多个配置文件,可以将括号中的信息配置为一个字符串数组
@ContextConfiguration({"file:src/main/webapp/WEB-INF/springmvc.xml", "classpath:META-INF/spring/applicationContext-*.xml"})
public class TestDemoController {

Logger logger = Logger.getLogger(TestDemoController.class);

@InjectMocks
private PageableHandlerMethodArgumentResolver pageableArgumentResolver;

private MockMvc mockMvc;

//使(@mock注解的对象)的使用类可以注入mock对象,这个例子中mock对象时userService,
// //使用mock对象的是userController,所以userController需要加上 @InjectMocks
@Mock//注入mocks对象
private DemoService demoService;

@InjectMocks
private DemoController demoController;

@Before
public void setup() {
//将打上Mockito标签的对象起作用,使得mock的类被mock,使用了mock对象的类自动与mock对象关联.
MockitoAnnotations.initMocks(this);
//这个对象时controler单元测试的关键,它的初始化也是在setup方法里面.
this.mockMvc = MockMvcBuilders.standaloneSetup(demoController).setCustomArgumentResolvers(pageableArgumentResolver).build();
}

@Test
public void should_return_demos_when_request_success() throws Exception {
//构造桩模块
Page<Demo> pages = fetchPageData();
when(demoService.findAll(any(DemoQuery.class), any(PageRequest.class))).thenReturn(pages);
mockMvc.perform(get("/api/v1/demos"))
.andDo(print())
.andExpect(status().isOk());
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐