2017-09-06 90 views
0

我有Spring Boot Application,我想測試它。我不使用Spring控制器,但我使用服務方法的Servlet。另外我有我的配置類,提供ServletRegistrationBean。 但每次我嘗試執行模擬請求時,都會收到404錯誤。根本沒有對servlet的調用。我認爲Spring沒有找到這個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}); 
    } 
} 

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); 
     } 
    } 
} 
+0

你不能使用'MockMvc'。 'MockMvc'在內部保存了一個特定的'DispatcherServlet',並且旨在用於Spring MVC測試(意味着存在於'DispatcherServlet'中的所有東西)。 –

回答

0

如果你真的想用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處理,並且因而可以使用MockMvc進行測試。

+0

SimpleUrlHandlerMapping不起作用。但是如果@Bean(name =「/ path/*」)在HttpRequestHandler上面指定的一切正常,但是在這個請求中servletPath字段是空的,如果我通過MockHttpServletRequestBuilder指定它,請求就不會再被處理 –

+0

爲什麼你需要servlet路徑? –

+0

OData處理器中需要Servlet路徑,如果沒有它,應用程序將失敗 –