Spring引导测试无法识别servlet

时间:2017-09-06 11:33:44

标签: java spring servlets junit spring-boot-test

我有Spring Boot Application,我想测试一下。我不使用Spring Controllers,但我使用Servlet和服务方法。我也有我的配置类提供ServletRegistrationBean。 但每当我尝试执行模拟请求时,我都会收到404错误。根本没有调用servlet。我认为Spring没有找到这个servlet。我该怎么办呢?当我在localhost启动app时,一切正常。

测试:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class SpringDataProcessorTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void retrieveByRequest() throws Exception{
        mockMvc.perform(buildRetrieveCustomerByIdRequest("1")).andExpect(status().isOk());

    }

    private MockHttpServletRequestBuilder buildRetrieveCustomerByIdRequest(String id) throws Exception {
        return get(String.format("/path/get('%s')", id)).contentType(APPLICATION_JSON_UTF8);
    }
}

配置:

@Configuration
public class ODataConfiguration extends WebMvcConfigurerAdapter {
    public String urlPath = "/path/*";


    @Bean
    public ServletRegistrationBean odataServlet(MyServlet servlet) {
        return new ServletRegistrationBean(servlet, new String[] {odataUrlPath});
    }
}

MyServlet:

@Component
public class MyServlet extends HttpServlet {

    @Autowired
    private ODataHttpHandler handler;


    @Override
    @Transactional
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try {
            handler.process(req, resp);
        } catch (Exception e) {
            log.error("Server Error occurred", e);
            throw new ServletException(e);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

如果您确实想使用MockMvc来测试代码而不是Servlet,请使用HttpRequestHandler并使用SimpleUrlHandlerMapping将其映射到网址。

如下所示。

@Bean
public HttpRequestHandler odataRequestHandler(ODataHttpHandler handler) {
    return new HttpRequestHandler() {
        public void handleRequest() {
            try {
                handler.process(req, resp);
            } catch (Exception e) {
                log.error("Server Error occurred", e);
                throw new ServletException(e);
            }
        }
    }
}

对于映射

@Bean
public SimpleUrlHandlerMapping simpleUrlHandlerMapping() {
    SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
    mapping.setUrlMap(Collections.singletonMap(odataUrlPath, "odataRequestHandler"); 
    return mapping;
}

另一种解决方案是将其包装在控制器而不是servlet中。

@Controller
public class ODataController {

    private final ODataHttpHandler handler;

    public ODataController(ODataHttpHandler handler) {
        this.handler=handler;
    }

    @RequestMapping("/path/*")
    public void process(HttpServletRequest request, HttpServletResponse response) throws ServletException {
        try {
            handler.process(req, resp);
        } catch (Exception e) {
            log.error("Server Error occurred", e);
            throw new ServletException(e);
        }
    }
}

无论哪种方式,您的处理程序都应由DispatcherServlet提供/处理,因此可以使用MockMvc进行测试。