使用Pageable参数对RestController进行单元测试时获取BeanInstantiationException

时间:2017-07-12 04:59:52

标签: java unit-testing spring-boot

我正在使用Spring Boot 1.5.4开发RESTful服务应用程序。

我的资源类中的一个方法(findAll)使用Pageable参数并使用它来调用服务方法。我正在单元测试这个方法时得到 BeanInstantiationException

这是我的资源类 -

@RestController
@RequestMapping("/api/v1/users")
public class UserResource {

    private final UserService userService;

    @Autowired
    public UserResource(UserService userService) {
        this.userService = userService;
    }

    @GetMapping("")
    public ResponseEntity<List<User>> findAll(Pageable pageable) {
        log.debug("REST request to get a page of Users");
        Page<User> page = userService.findAll(pageable);
        HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/api/v1/users");
        return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK);
    }
}

这是我的服务类 -

@Service
@Transactional
public class UserServiceImpl implements UserService {

    private final UserRepository userRepository;

    @Autowired
    public UserServiceImpl(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    @Transactional(readOnly = true)
    public Page<User> findAll(Pageable pageable) {
        return userRepository.findAll(pageable);
    }
}

这是我的测试类 -

@RunWith(SpringRunner.class)
@WebMvcTest(UserResource.class)
public class UserResourceTest {

    private static final ObjectMapper mapper = new ObjectMapper();

    @Autowired
    private MockMvc mvc;

    @MockBean
    private UserService userService;

    private static final Long DEFAULT_ID = 1L;
    private static final String DEFAULT_EMAIL = "test@test.com";
    private static final String DEFAULT_FIRSTNAME = "john";
    private static final String DEFAULT_LASTNAME = "doe";
    private static final String DEFAULT_PASSWORD = "ABCDEFGHJIABCDEFGHJIABCDEFGHJIABCDEFGHJIABCDEFGHJIABCDEFGHJI";
    private static final UserStatus DEFAULT_STATUS = UserStatus.ACTIVE;
    private static final String DEFAULT_PHONE = "12345679";

    public static User createUserWithOutId() {
        User user = new User();
        user.setEmail(DEFAULT_EMAIL);
        user.setFirstName(DEFAULT_FIRSTNAME);
        user.setLastName(DEFAULT_LASTNAME);
        user.setPassword(DEFAULT_PASSWORD);
        user.setStatus(DEFAULT_STATUS);
        user.setPhone(DEFAULT_PHONE);
        return user;
    }

    public static User createUserWithId() {
        User user = createUserWithOutId();
        user.setId(DEFAULT_ID);
        return user;
    }

    @Test
    public void findAll_WhenUsersExist_ShouldReturnUsersList() throws Exception {
        final User user = createUserWithId();
        List<User> users = Arrays.asList(user);
        Page<User> page = new PageImpl<>(users, new PageRequest(0, 10), users.size());
        when(userService.findAll(any(PageRequest.class)))
                .thenReturn(page);
        mvc.perform(get("/api/v1/users").accept(MediaType.APPLICATION_JSON_VALUE))
                .andExpect(status().isOk());
    }
}

异常的堆栈跟踪 -

Tests run: 7, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.76 sec <<< FAILURE! - in bd.com.ronnie.accountservice.web.rest.UserResourceTest
findAll_WhenUsersExist_ShouldReturnUsersList(bd.com.ronnie.accountservice.web.rest.UserResourceTest)  Time elapsed: 0.041 sec  <<< ERROR!
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.beans.BeanUtils.instantiateClass(BeanUtils.java:99)
        at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.createAttribute(ModelAttributeMethodProcessor.java:141)
        at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.createAttribute(ServletModelAttributeMethodProcessor.java:81)
        at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:101)
        at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121)
        at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:158)
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128)
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
        at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:65)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
        at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:167)
        at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
        at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
        at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
        at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:155)
        at bd.com.ronnie.accountservice.web.rest.UserResourceTest.findAll_WhenUsersExist_ShouldReturnUsersList(UserResourceTest.java:97)

1 个答案:

答案 0 :(得分:0)

MockMvc.class不是由spring管理的,如果使用@Autowired来标记类,则不能注入该字段,因此它告诉你“Specified class is a interface”。这是一个例子。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@WebAppConfiguration
public class Test {

    @Autowired
    private WebApplicationContext context;

    private MockMvc mvc;

    @Before
    public void setup() {
        mvc = MockMvcBuilders
                .webAppContextSetup(context)
                .build();
    }
}

如果它不起作用,我想 get("/api/v1/users")不会创建requestAttr的PageRequest,因为界面UserResource.findAll需要Pageable。

get("/api/v1/users").requestAttr("pageable", new PageRequest(1,2))