Skip to content

skjolber/mockito-soap-cxf

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Build Status Maven Central

mockito-soap-cxf

SOAP web-service mocking utility which creates real service endpoints on local ports using webserver instances. These endpoints delegate requests directly to mocks.

Users will benefit from

  • full stack client testing
    • interceptors
    • handlers
  • simple JUnit Rule setup
  • SOAP-Fault helper

all with the regular advantages of Mockito.

Bugs, feature suggestions and help requests can be filed with the issue-tracker.

License

Apache 2.0

Obtain

The project is based on Maven and is available form central Maven repository.

Maven coordinates

Add

<mockito-soap-cxf.version>2.0.0</mockito-soap-cxf.version>

and

<dependency>
    <groupId>com.github.skjolber</groupId>
    <artifactId>mockito-soap-cxf</artifactId>
    <version>${mockito-soap-cxf.version}</version>
</dependency>

or

Gradle coordinates

For

ext {
  mockitoSoapCxfVersion = '2.0.0'
}

add

api("com.github.skjolber:mockito-soap-cxf:${mockitoSoapCxfVersion}")

For JDK 9+, add module com.github.skjolber.mockito.soap.

For JDK 8 or 11 use the 1.2.x series (override spring and mockito dependency versions).

Usage

Junit 5

If you prefer skipping to a full example, see this unit test.

Basics

Add a SoapServiceExtension

@ExtendWith(SoapServiceExtension.class)

and mock service endpoints by using

private MyServicePortType serviceMock;

@BeforeEach
public void setup(SoapServiceExtension soap) {
  serviceMock = soap.mock(MyServicePortType.class, "http://localhost:12345");
}

or, preferably

private MyServicePortType serviceMock;

@BeforeEach
public void setup(SoapServiceExtension soap) {
  soap.mock(MyServicePortType.class, "http://localhost:12345", Arrays.asList("classpath:wsdl/MyService.xsd"));
}

for schema validation. The returned serviceMock instance is a normal Mockito mock(..) object.

JUnit 4

If you prefer skipping to a full example, see this unit test.

Basics

Create a SoapServiceRule

@Rule
public SoapServiceRule soap = SoapServiceRule.newInstance();

add a field

private MyServicePortType serviceMock;

and mock service endpoints by using

@Before
public void mockService() {
  serviceMock = soap.mock(MyServicePortType.class, "http://localhost:12345");
}

or, preferably

serviceMock = soap.mock(MyServicePortType.class, "http://localhost:12345", Arrays.asList("classpath:wsdl/MyService.xsd"));

for schema validation. The returned serviceMock instance is a normal Mockito mock(..) object.

Mocking

Create mock response via code

// init response
GetAccountsResponse mockResponse = new GetAccountsResponse();
List<String> accountList = mockResponse.getAccount();
accountList.add("1234");
accountList.add("5678");

or from XML

GetAccountsResponse response = jaxbUtil.readResource("/my/test/GetAccountsResponse1.xml", GetAccountsResponse.class);

using your favorite JAXB utility. Then mock

when(serviceMock.getAccounts(any(GetAccountsRequest.class))).thenReturn(mockResponse);

and apply standard Mockito test approach. After triggering calls to the mock service, verify number of method calls

ArgumentCaptor<GetAccountsRequest> argument1 = ArgumentCaptor.forClass(GetAccountsRequest.class);
verify(serviceMock, times(1)).getAccounts(argument1.capture());

and request details

GetAccountsRequest request = argument1.getValue();
assertThat(request.getCustomerNumber(), is(customerNumber));

SOAP Faults

Mock SOAP faults by adding import

import static com.skjolberg.mockito.soap.SoapServiceFault.*;

then mock doing

when(serviceMock.getAccounts(any(GetAccountsRequest.class))).thenThrow(createFault(exception));

or mock directly using an XML string / w3c DOM node.

MTOM (binary attachments)

CXF SOAP clients support MTOM of out the box, enable MTOM in the service mock using

serviceMock = soap.mock(BankCustomerServicePortType.class, bankCustomerServiceAddress, properties("mtom-enabled", Boolean.TRUE));

and add a DataHandler to the mock response using

byte[] mockData = new byte[] {0x00, 0x01};
DataSource source = new ByteArrayDataSource(mockData, "application/octet-stream");
mockResponse.setCertificate(new DataHandler(source)); // MTOM-enabled base64binary

See MTOM unit test for an example.

Running in parallel (Junit 4 only)

For use-cases which require test-cases to run in parallel, it is possible to mock endpoints on random (free) ports. For the SoapEndpointRule methods

@ClassRule
public static SoapEndpointRule soap = SoapEndpointRule.newInstance("myPort", "yourPort");

or with port range

@ClassRule
public static SoapEndpointRule soap = SoapEndpointRule.newInstance(10000, 30000, "myPort", "yourPort");

there will be reserved two random free ports. Ports numbers can be retrieved using.

int myPort = soap.getPort("myPort");

and

String myPort = System.getProperty("myPort");

In other words, for property resolvers which include system-properties, the reserved ports are readily available. For example the Spring property expression

http://localhost:${myPort}/selfservice/bank

would effectively point to the mocked webservice at myPort. For a more complete example, see this spring unit test.

Troubleshooting

There seems to be an issue with the use of the -exsh parameter for passing headers into the mock and schema validation. Rather than supplying the wsdl location, supply the XSD locations to work around the problem until a solution can be found.

CXF version 2.x

If you see exception cause by

No binding factory for namespace http://schemas.xmlsoap.org/soap/ registered.

then you're mixing CXF version 2 and 3 - see above about excluding cxf-core artifact.

History

  • 2.0.0: Move to JDK 17 and Spring 6.x and Mockito 5.x.
  • 1.2.1: Maintainence release. JDK 8 (with CXF 3.x and Spring 5.3.x now live at jdk8 branch, on version 1.2.x).
  • 1.2.0: JUnit 5 support.
  • 1.1.0: Automatic module name; renamed packages accordingly.
  • 1.0.5: A lot of refactorings and code cleanups, update dependencies and fix port release - many thanks to amichair!
  • 1.0.4: Allow the usage of local:// transport - compliments of aukevanleeuwen
  • 1.0.3: MTOM support
  • 1.0.2: Support for mocking on (random) free ports (via SoapEndpointRule).
  • 1.0.1: Improved JAXB helper methods in SoapServiceFault
  • 1.0.0: Initial version