Spring 引导测试无法识别 servlet

Spring boot test not recognizing servlet

我有 Spring 启动应用程序,我想测试它。我不使用 Spring 控制器,但我使用带有服务方法的 Servlet。此外,我还有提供 ServletRegistrationBean 的配置 class。 但是每次当我尝试执行模拟请求时,我都会收到 404 错误。根本没有对 servlet 的调用。我认为 Spring 没有找到这个 servlet。我该如何解决?当我在本地主机上启动应用程序时,一切正常。

测试:

@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});
    }
}

我的Servlet:

@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);
        }
    }
}

如果您真的想使用 MockMvc 来测试您的代码而不是 Servlet,请使用 HttpRequestHandler 并使用 SimpleUrlHandlerMapping 将其映射到 URL。

类似下面的内容。

@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 的 served/processed,因此可以使用 MockMvc 进行测试。