I want to ask you if it is possible in SOAPUI to alter a mock response, and link it to the real web service operation in which the MockService is based on.
I need to do that because within SOAPUI I can reach to external webservices; BUT for security/configuration reasons, I can’t access to this external webservices inside my local code in my Eclipse (I have tried several proxy configurations in my Eclipse without success).
What I want to do is to pass the request that reach to the mock service to the original web service and return the response without manipulation.
You can create a mockService in SOAPUI to redirect your request to a 3rd party service as follows:
First creat a mockService in your project: right click on your project > New SOAP MockService
Then creat a mockOperation on it: right click on your MockService > New MockOperation
Inside your mockOperation there is a request created, open it an put for example the follow code as a response: ${myResponse}. This name is bind to a variable which will fill then with a script.
Finally open your mockOperation and use the follow script to hit your 3rd party service redirecting the original request:
final HttpURLConnection connection = 'http://yourService:8080'.toURL().openConnection()
connection.setDoOutput(true)
// copy the headers
mockRequest.getRequestHeaders().each { name, value ->
connection.setRequestProperty(name,value.toString())
}
// write the request
connection.outputStream.withWriter { Writer writer ->
writer << mockRequest.requestContent
}
// get the response
String response = connection.inputStream.withReader { Reader reader -> reader.text }
// set the response in your variable
requestContext.myResponse = response
Hope this helps,
I finally did it turning 'Dispatch' to SCRIPT and adding this script:
// import all the namespaces to trim the lines of codes
import com.eviware.soapui.impl.wsdl.WsdlProject
import com.eviware.soapui.impl.wsdl.WsdlInterface
import com.eviware.soapui.impl.wsdl.WsdlRequest
import com.eviware.soapui.impl.wsdl.WsdlSubmitContext
import com.eviware.soapui.impl.wsdl.WsdlSubmit
import com.eviware.soapui.model.iface.Response
import com.eviware.soapui.model.mock.MockResponse
// get reference to project
WsdlProject project = (WsdlProject)mockOperation.mockService.project
// get reference to request
WsdlRequest request = (WsdlRequest)project.interfaces["TheRealWebService"].operations["TheRealOperation"].getRequestByName("TheRealRequest")
// set request content from incoming mockRequest
request.setRequestContent(mockRequest.getRequestContent())
// submit request asynchronously
WsdlSubmit submit=request.submit( new WsdlSubmitContext( request ), false )
// wait for the response
Response response = submit.getResponse();
// get reference to MockResponse
MockResponse mockResponse=mockOperation.getMockResponseByName("Response1")
// set the mock response content from response received by the request.
mockResponse.setResponseContent(response.getContentAsString())
Related
I'm currently trying to mock external server using Wiremock.
One of my external server endpoint takes a payload.
This endpoint is defined as follow :
def sendRequestToMockServer(payload: String) = {
for {
request_entity <- Marshal(payload).to[RequestEntity]
response <- Http().singleRequest(
HttpRequest(
method = HttpMethods.GET,
uri = "http://localhost:9090/login",
entity = request_entity
)
)
} yield {
response
}
}
To mock this endpoint using Wiremock, I have written the following code :
stubFor(
get(urlEqualTo("/login"))
.willReturn(
aResponse()
.withHeader("Content-Type","application/json")
.withBodyFile("wireMockResponse.json")
.withStatus(200)
)
.withRequestBody(matchingJsonPath("requestBody.json"))
)
where I Have defined the request body in the requestBody.json file.
But when I run tests , I keep getting an error indicating that the requested Url is not found.
I'm thinking that the error is related to this line withRequestBody(matchingJsonPath("requestBody.json")), because when I comment it the error disappear.
Any suggestions on how to work around this?
matchingJsonPath does not populate a file at a provided filepath, but instead evaluates the JsonPath provided. See documentation.
I'm not entirely sure there is a way to provide the request body as a .json file. If you copy the contents of the file into the withRequest(equalToJson(_yourJsonHere_)), does it work? If it does, you could get the file contents as a JSON string above the definition and provide it to the function (or I guess, make a function to return a JSON string from a .json file).
Additionally, you could make a custom request matcher that does the parsing for you. I think I'd recommend this only if the above does not work.
I have a REST API project in SOAP UI which contains 20 test cases in a test suite. I want to add some header value and sslkeystore in every test step. Here is my code.
import com.eviware.soapui.support.types.StringToStringMap
testCaseList = testSuite.getTestCases()
testCaseList.each
{
testCase = testSuite.getTestCaseByName(it.key)
restTestSteps = testCase.getTestStepsOfType(com.eviware.soapui.impl.wsdl.teststeps.RestTestRequestStep)//only RestTestRequest steps
restTestSteps.each
{
it.getRestRequest().setHttpHeader("TEST2")
it.testRequest.setSslKeystore("**************")
}
}
Above code "TEST2" contains the header value that I want to add to every test cases. I have configured TEST2 in ws-security configuration under outgoing ws-security configuration.
But in above code I am getting following error:
groovy.lang.MissingMethodException: No signature of method: com.eviware.soapui.impl.wsdl.teststeps.RestTestRequestStep.getRestRequest() is applicable for argument types: () values: [] Possible solutions: getTestRequest(), getHttpRequest()
Anybody help me please how can I add header value in every test steps.
If you want to set the header values for each step in a test case, you can create a groovy test step that will do this. Place the groovy step at the beginning of the test case and it will work even if you change or add new steps. I'm sure you could tweak the getAllHttpSteps to include all test cases in the suite as well, and place this as the first test run.
/**
* This script populates all http requests in a test case with headers:
*/
import com.eviware.soapui.support.types.StringToStringMap
// make a list of all http rest requests
getAllHttpSteps=testRunner.testCase.getTestStepsOfType(com.eviware.soapui.impl.wsdl.teststeps.RestTestRequestStep)
// iterate through the list of requests and populate the request headers
for (step in getAllHttpSteps)
{
def headers = new StringToStringMap()
headers.put("SomeHeader", "SomeHeaderValue")
headers.put("sslKeystore", "keystoreValue")
}
If you want to add header value and sslkeystore in every test step, then add these values as Properties OR Custom Properties in Project. Then assign these values in each step. Are you willing to do this with groovy script?
I'm newbie to soap and soapui, I'm trying to create a test case in which I will send the same request(XML attachment) many times(about 500), the problem is that each time I need to increment/change a value in the request (the id).
Therefore, I wonder if the is a way to pass this parameter to the attached xml file ? or if there is another ways to do the test case.
Thank you in advance
UPDATE
here is the content of the xml file :
<mod:sendMSG xmlns:mod="http://test.soap/service/model">
<id>${#Project#parameter1}</id>
<date>2016-04-03T04:03:00</date>
<infos>
<firstName>AT </firstName>
<lastName>AT </lastName>
......
</infos>
</mod:sendMSG>
which is included in the soap request, ass shown in the following image :
Test steps:
Groovy Script
SOAP Request (disabled)
I disabled the SOAP Request because it runs once more after the script has already looped the request x times.
Groovy script:
int loops = 500;
for ( iter in 1..loops ) {
//Overwrite the 'parameter1' property at project level
testRunner.testCase.testSuite.project.setPropertyValue("parameter1", iter.toString())
//log.info("iter: " + testRunner.testCase.testSuite.project.getPropertyValue("parameter1"));
// Run the teststep named 'SOAP Request'
def testStep = testRunner.testCase.testSteps['SOAP Request'];
testStep.run( testRunner, context )
}
Now you should be able to run your TestCase. I recommend saving your project before, I had some problems with SoapUI crashing on me when running.
I've followed the tutorial on the soap ui mocking page to return back dynamic xml responses based on a Groovy script created in soap ui.
The sample responses live in the project root. i.e. Where the Groovy script returns a response the code in the script looks like this ...
import com.eviware.soapui.support.GroovyUtils
import groovy.xml.XmlUtil
def groovyUtils = new GroovyUtils(context)
def xmlParser = new XmlParser()
def responseContent = xmlParser.parse(groovyUtils.projectPath + "/responses/get-veh-details-response-one.xml")
context.content = XmlUtil.serialize(responseContent)
I now need to export the mock as a .war file and get it deployed to a server. Does soap ui allow me somehow to include my "/responses/get-veh-details-response-one.xml" inside the war?
I have to implement a Vertx POST request. Via Postman, the request is done as shown in the following picture:
The tricky part is that the server expects the key "upgrade_file" for the body. I could not find out how to do that with Vertx. This is what I have so far:
Buffer bodyBuffer = Buffer.buffer(body); // body is byte[]
HttpClientRequest request = ...
request.handler( response -> ...
request.end(bodyBuffer);
How can I set "upgrade_file" as the key for the body?
Use a WebClient instead of the HTTP client, it provides dedicated support for submitting forms.
WebClient client = WebClient.create(vertx);
or if you already have created an http client:
WebClient client = WebClient.wrap(httpClient);
Then create the form data as map and send the form using a the right content type
MultiMap form = MultiMap.caseInsensitiveMultiMap();
form.set("upgrade_file", "...");
// Submit the form as a multipart form body
client.post(8080, "yourhost", "/some_address")
.putHeader("content-type", "multipart/form-data")
.sendForm(form, ar -> {
//do something with the response
});
More example see https://vertx.io/docs/vertx-web-client/java/
If you want to send files, the simplest way is using the sendMultipartForm method of Vertx WebClient.
Create a Multipartform firstly.
MultipartForm form = MultipartForm.create()
.attribute("imageDescription", "a very nice image")
.binaryFileUpload(
"imageFile",
"image.jpg",
"/path/to/image",
"image/jpeg");
Then invoke WebClient.sendMultipartForm(form) to send the request.
The generic Vertx HttpClient is a low-level API, you should searialize the form data into a string or buffer, the format is similar to this example file in Vertx GraphQL testing codes. Then send the buffer to the server side.