Java Spring中配置WebServiceServerTest与MockWebServiceClient进行SOAP测试
解决Spring SOAP测试中自定义Endpoint拦截器未生效的替代方案
针对你在Spring SOAP服务测试中遇到的自定义拦截器不生效问题,除了@SpringBootTest + @AutoConfigureMockWebServiceClient的组合,还有以下几种轻量且精准的解决方案:
1. 手动向MockWebServiceClient注册拦截器
@WebServiceServerTest默认不会自动加载完整的拦截器配置,但可以在测试初始化时,手动将自定义拦截器添加到MockWebServiceClient的拦截器链中:
@WebServiceServerTest(YourSoapEndpoint.class) class SoapEndpointInterceptorTest { @Autowired private ApplicationContext context; @Autowired private YourCustomEndpointInterceptor customInterceptor; private MockWebServiceClient client; @BeforeEach void setUp() { // 创建客户端时手动注入自定义拦截器 client = MockWebServiceClient.createClient(context) .interceptors(customInterceptor); } @Test void testInterceptorModifiesResponse() { // 构造SOAP请求体 String requestPayload = "<soap:Envelope>...</soap:Envelope>"; // 预期拦截器修改后的响应体 String expectedResponse = "<soap:Envelope>...</soap:Envelope>"; client.sendRequest(withPayload(requestPayload)) .andExpect(payload(expectedResponse)); // 验证拦截器的交互逻辑,比如检查捕获的请求内容 assertThat(customInterceptor.getCapturedRequestContent()).isNotBlank(); } }
这种方式仅加载必要的Endpoint组件,比全上下文启动更高效,同时确保拦截器参与请求处理流程。
2. 为@WebServiceServerTest指定自定义配置类
创建一个测试专用的Spring配置类,显式注册拦截器到Spring WS的拦截器链中,再通过@WebServiceServerTest加载该配置:
// 测试专用配置类,注册拦截器 @TestConfiguration static class TestSoapInterceptorConfig implements WsConfigurer { @Bean public YourCustomEndpointInterceptor customEndpointInterceptor() { return new YourCustomEndpointInterceptor(); } @Override public void addInterceptors(List<EndpointInterceptor> interceptors) { interceptors.add(customEndpointInterceptor()); } } // 指定要测试的Endpoint和自定义配置类 @WebServiceServerTest( endpoints = YourSoapEndpoint.class, classes = TestSoapInterceptorConfig.class ) class SoapEndpointTest { @Autowired private MockWebServiceClient client; @Autowired private YourCustomEndpointInterceptor customInterceptor; @Test void testInterceptorBehavior() { // 测试逻辑:发送请求,验证拦截器对响应的修改 client.sendRequest(withPayload("<request>...</request>")) .andExpect(payload("<modified-response>...</modified-response>")); // 验证拦截器的方法是否被调用 verify(customInterceptor, times(1)).handleRequest(any(), any(), any()); } }
该方案既保持了@WebServiceServerTest的轻量性,又能让拦截器通过配置类被Spring WS上下文识别。
3. 基于MockMvc直接配置MessageDispatcherServlet
如果需要更底层的控制,可以手动配置Spring WS的MessageDispatcherServlet,注册拦截器后用MockMvc发送请求:
@ExtendWith(SpringExtension.class) @ContextConfiguration(classes = {YourSoapEndpoint.class}) class SoapEndpointMockMvcTest { private MockMvc mockMvc; @Autowired private YourCustomEndpointInterceptor customInterceptor; @BeforeEach void setUp() { // 手动配置MessageDispatcherServlet并注册拦截器 MessageDispatcherServlet servlet = new MessageDispatcherServlet(); AnnotationConfigApplicationContext servletContext = new AnnotationConfigApplicationContext(); servletContext.register(WsTestConfig.class); servletContext.refresh(); servlet.setApplicationContext(servletContext); mockMvc = MockMvcBuilders.standaloneSetup(servlet).build(); } // 配置WS基础组件和拦截器 @TestConfiguration static class WsTestConfig implements WsConfigurer { @Override public void addInterceptors(List<EndpointInterceptor> interceptors) { interceptors.add(new YourCustomEndpointInterceptor()); } @Bean public DefaultWsdl11Definition defaultWsdl11Definition() { DefaultWsdl11Definition wsdlDefinition = new DefaultWsdl11Definition(); wsdlDefinition.setPortTypeName("YourServicePort"); wsdlDefinition.setLocationUri("/soap/services"); // 补充XSD、命名空间等配置 return wsdlDefinition; } } @Test void testSoapRequestWithInterceptor() throws Exception { String soapRequest = "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">...</soap:Envelope>"; mockMvc.perform(post("/soap/services") .contentType(MediaType.TEXT_XML) .content(soapRequest)) .andExpect(status().isOk()) .andExpect(content().xml("<expected-modified-response>...</expected-modified-response>")); } }
这种方式适合需要完全控制Servlet初始化流程的场景,灵活性极高,但配置相对繁琐。
内容的提问来源于stack exchange,提问作者Eugene
相关产品推荐
相关产品推荐

