SoapUI mocking asynchronous services

2020-07-18 07:00发布

问题:

We use SoapUI to mock web services to test our application (APP) before we have access to real webservices.

Creating a synchronous Mock Service which will return predefined response is straightforward. However I have to mock some asynchronous services where the APP sends a request, the SoapUI immediately responds back with confirmation (e.g. SUCCESS) and then after a predefined interval the SoapUI will call our application back (the APP is then acting as a server). I managed to do it using test case where first step is MockResponse, then delay and then MockRequest (to call our app).

The above works fine but I'd like to do it by scripting it directly in the Mock Reponse to avoid using Test Cases. I managed to write the script which when a Mock Service receives request it will fire the callback.

def project = result.mockOperation.mockService.project
// The API documentation doesn't say what finish is supposed to do but I try (doesn't help)
result.finish()
// Request that will be returned back - THE CALLBACK
def request = project.interfaces["LocationServicesOperation"].operations["ackLocation"].getRequestByName("Request 1")
sleep(4000)
request.submit(new com.eviware.soapui.impl.wsdl.WsdlSubmitContext(  ), false)

The issue with the above is that it will fire the callback BEFORE sending the response for the initial request. I tried using event handling in SoapUI PRO but I can't get that working. In Wireshark I can see the communication like this:

1) APP request -> SoapUI 
2) SoapUI callback -> APP
3) APP confirms 2) -> SoapUI 
4) SoapUI confirms 1) -> APP

However it needs to be:

1) APP request -> SoapUI 
2) SoapUI confirms 1) -> APP
3) SoapUI callback -> APP
4) APP confirms 2) -> SoapUI 

The code above is actually from MockRunListener.onMockResult event in SoapUI Pro. the result.finish() doesn't do the trick.

Thanks for any tips!

回答1:

I finally found a solution at http://www.eviware.com/forum/viewtopic.php?f=5&t=3542&p=12474&hilit=asynchronous#p12474

The trick was instead of dispatching the request directly from within the response script to add the callback request to a test and then call the test. This will cause the mock runner to first send response to the request and after that run the test case.

The advantage is that the test case is triggered dynamically and doesn't need to run all the time.