我正在为使用 JaxWsProxyFactoryBean 创建代理并设置一些属性的方法编写单元测试。但是,在尝试模拟 ClientProxy.getClient() 方法时,我遇到了 java.lang.IllegalArgumentException: not a proxy instance 错误。
这是我正在测试的课程:
import javax.xml.namespace.QName;
import javax.xml.ws.soap.SOAPBinding;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.frontend.JaxWsProxyFactoryBean;
import org.apache.cxf.transport.http.HTTPConduit;
public class MyClassUnderTest {
private String endpointAddress;
private String serviceName;
public MyService myServiceCreateProxy() {
MyService result = null;
JaxWsProxyFactoryBean proxy = new JaxWsProxyFactoryBean();
proxy.setServiceClass(MyService.class);
proxy.setAddress(endpointAddress);
proxy.setServiceName(new QName(serviceName));
proxy.setEndpointName(new QName("http://example/MyService", "MyServicePort"));
proxy.setBindingId(SOAPBinding.SOAP12HTTP_BINDING);
proxy.getOutInterceptors().add(mySecurityInterceptor());
result = (MyService) proxy.create();
ClientProxy.getClient(result).getOutInterceptors().add(new MyRequestInterceptor());
HTTPConduit conduit = (HTTPConduit) ClientProxy.getClient(result).getConduit();
conduit.getClient().setConnectionTimeout(300000);
conduit.getClient().setReceiveTimeout(300000);
return result;
}
private MyRequestInterceptor mySecurityInterceptor() {
return new MyRequestInterceptor();
}
}
测试班:
import static org.mockito.Mockito.*;
import static org.testng.Assert.*;
import javax.xml.namespace.QName;
import javax.xml.ws.soap.SOAPBinding;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.frontend.JaxWsProxyFactoryBean;
import org.apache.cxf.transport.http.HTTPConduit;
import org.mockito.Answers;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class MyServiceTest {
@Mock
private JaxWsProxyFactoryBean proxyFactoryMock;
@Mock
private MyService myServiceMock;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Client clientMock;
@Mock
private HTTPConduit httpConduitMock;
@Mock
private MyRequestInterceptor myRequestInterceptorMock;
@InjectMocks
private MyClassUnderTest classUnderTest;
@BeforeMethod
public void setUp() {
MockitoAnnotations.initMocks(this);
when(proxyFactoryMock.create()).thenReturn(myServiceMock);
when(ClientProxy.getClient(myServiceMock)).thenReturn(clientMock);
when(clientMock.getConduit()).thenReturn(httpConduitMock);
}
@Test
public void testMyServiceCreateProxy() {
MyService result = classUnderTest.myServiceCreateProxy();
assertNotNull(result);
verify(proxyFactoryMock).setAddress(anyString());
verify(proxyFactoryMock).setServiceClass(MyService.class);
verify(proxyFactoryMock).setBindingId(SOAPBinding.SOAP12HTTP_BINDING);
verify(clientMock.getOutInterceptors()).add(any(MyRequestInterceptor.class));
verify(httpConduitMock.getClient()).setConnectionTimeout(300000);
verify(httpConduitMock.getClient()).setReceiveTimeout(300000);
}
}
运行测试时,遇到以下错误:
java.lang.IllegalArgumentException: not a proxy instance
at org.apache.cxf.frontend.ClientProxy.getClient(ClientProxy.java:127)
...
setUp方法中的这一行出现错误:
when(ClientProxy.getClient(myServiceMock)).thenReturn(clientMock);
似乎 myServiceMock 没有被识别为代理实例,这是 ClientProxy.getClient() 工作所必需的。
如何正确模拟 ClientProxy.getClient() 方法以避免单元测试中出现“不是代理实例”错误?有没有更好的方法来测试涉及 JaxWsProxyFactoryBean 和 ClientProxy 的方法?
任何见解或建议将不胜感激。
我经常通过服务/包装类包含第三方包中的类。我不想测试第三方包中的类。这使得模拟变得更容易,特别是当涉及静态方法调用时。
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.endpoint.Client;
public class ClientProxyService {
public Client getClient(Object object) {
return ClientProxy.getClient(object);
}
}
ClientProxyService clientProxyServiceMock = mock(ClientProxyService.class);
when(clientProxyServiceMock.getClient(myServiceMock)).thenReturn(clientMock);