CXF客户端JUnit测试遇ClassCastException:Mock实例无法转为BindingProvider
解决CXF客户端Mock时的BindingProvider类型转换异常
Mockito默认Mock的CXF客户端类实例,不会自动保留原类实现的BindingProvider接口能力,导致类型转换失败。下面是几种最简解决方案:
方法1:给Mock实例添加额外接口
直接让Mockito生成的Mock对象同时实现BindingProvider接口,之后MockgetRequestContext方法返回预设的地址即可。
如果手动创建Mock:
private MyService myService = Mockito.mock(MyService.class, Mockito.withSettings().extraInterfaces(BindingProvider.class)); // 预设请求上下文和地址 Map<String, Object> requestContext = new HashMap<>(); requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://mock-endpoint.com"); when(((BindingProvider) myService).getRequestContext()).thenReturn(requestContext);
如果用@Mock注解,搭配extraInterfaces参数:
@Mock(extraInterfaces = BindingProvider.class) private MyService myService; @BeforeEach void setUp() { MockitoAnnotations.openMocks(this); // 预设地址 Map<String, Object> requestContext = new HashMap<>(); requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://mock-endpoint.com"); when(((BindingProvider) myService).getRequestContext()).thenReturn(requestContext); }
方法2:Spy真实的CXF客户端实例
创建一个空的真实CXF客户端实例(不需要连接服务),用Mockito Spy包装它。这样既保留了原类的BindingProvider实现,又能Mock业务方法。
private MyService myService; @BeforeEach void setUp() { // 创建真实客户端实例(根据你的服务构造方法调整) MyService realService = new MyService(); myService = Mockito.spy(realService); // 直接设置Mock地址,无需处理类型转换 ((BindingProvider) myService).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://mock-endpoint.com"); // Mock业务方法示例 when(myService.yourBusinessMethod(any())).thenReturn(mockResponse); }
方法3:自定义可Mock的子类
如果前两种方法不适用,自己写一个继承CXF客户端类的子类,显式实现BindingProvider(实际CXF生成的类已实现,这里是为了确保Mockito能识别),然后Mock这个子类。
// 自定义子类 public class MockableMyService extends MyService implements BindingProvider { private final Map<String, Object> requestContext = new HashMap<>(); @Override public Map<String, Object> getRequestContext() { return requestContext; } @Override public Map<String, Object> getResponseContext() { return new HashMap<>(); } } // 测试类中使用 @Mock private MockableMyService myService; @BeforeEach void setUp() { MockitoAnnotations.openMocks(this); // 预设地址 myService.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://mock-endpoint.com"); // Mock业务方法 when(myService.yourBusinessMethod(any())).thenReturn(mockResponse); }
内容的提问来源于stack exchange,提问作者SereneAtk
相关产品推荐
相关产品推荐

