Mock/not-mock response on a per request basis in Integration test - java

I am writing Integration tests. I have a need where for a positive test case request hit an actual service and recieve the response. But for a negative test case I must get the mocked response.
I am curious to understand if there is a way that I can mock/not-mock the request on a per configuration basis. Like for example if request accepts email address in request and I provide
"invalid#email.com" - response from mockoon must be a mocked response.
"valid#email.com" - mocking must not happen but rather it must hit the actual server to get the response. may be via redirecting or calling the actual service and responding the response to the caller.
I have tried Mockoon but feature is not yet present. So trying to help from the community :)
Regards,

You can use separate stub/mappings that match on different emails.
Assuming that your url is some-Url and uses a queryParameter of email...
{
"request": {
"url": "/some-Url",
"queryParameters": {
"email": {
"equalTo": "invalid#email.com"
}
}
},
"response": {
"status": 200
}
}
{
"request": {
"url": "/some-Url",
"queryParameters": {
"email": {
"equalTo": "valid#email.com"
}
}
},
"response": {
"proxyBaseUrl": "http://my-other-url.com"
}
}

This is possible with mockswitch - it supports various request / response pairs kinda like a switch case. You can define different cases and do request matching based on for each. If one the case matches it breaks the response flow and responds. Also easy to proxy requests to actual service based on certain case.
Their docs is available here https://mockswitch.com/docs/#switch-case-responses

Related

How to get a URL in response of a POST request that navigates to GET request in Spring Boot?

I'm working on a project in which I'm creating (POST) a book. Once the book is created, a unique bookId is generated and the response looks something like this:
{
"bookId":"123pqr",
"author":"Abc",
"title": "Book1"
}
I have one GET request which basically fetches the book details using bookId - http://localhost:port/{bookId}.
I'm trying to get this above URL whenever I create a book so that my response should look like this:
{
"bookId":"123pqr",
"author":"Abc",
"title": "Book1"
"url": "http://localhost:port/{bookId}"
}
So that if a user clicks on the URL, the user should be navigated to a GET request http://localhost:port/{bookId}. I think I can just hardcode a string "http://localhost:port/" and then append bookId to it and provide the same in response. However, I'm not sure how to set the request type as GET when the URL is clicked. Also, is there a better way to avoid harcoding? Could someone please help? Thanks in advance!
You do not need to specify anything to consider a URL as a GET.
This is natively part of every browser.
However, you could think a bit further and use HATEOAS which specifies the kind of relationship for a specific href
Your response would look like the following where self is standardized to be a GET request since it's the retrieval of the resource
{
"bookId":"123pqr",
"author":"Abc",
"title": "Book1"
"_links": {
"self": {
"href": "http://localhost:port/{bookId}"
}
}
}
More information can be found here
Spring HATEOAS which BTW can also help with building the URI and thus no need to hardcode localhost and port making your app dynamic enough

Using Spring MVC and Kotlin, why does this Body is ignored?

I would like to know why this code runs but doesn't filter the data as it should.
The same request in postman works but in Kotlin it doesn't what is happening?
The goal is to filter the data by timestamp value.
val getFiltered = restTemplate.exchange(
"https://X.X.X.X:6200/ble_flow-$da/_search/?size=50&pretty=1",
HttpMethod.GET, HttpEntity("{\\r\\n\\\"query\\\": { \\r\\n \\\"bool\\\": { \\r\\n \\\"filter\\\": [ \\r\\n { \\\"range\\\": { \\\"timestamp\\\": { \\\"gte\\\": \\\"2019-08-12T06:00:00\\\",\\\"lt\\\":\\\"2019-08-12T011:00:00\\\"}}} \\r\\n ]\\r\\n }\\r\\n }\\r\\n}", headers),
ResultsFlow::class.java)
println(getFiltered)
It would solve the problem if I could transform the body:
{
"query": {
"bool": {
"filter": [
{ "range": { "timestamp": { "gte": "2019-08-12T06:00:00","lt":"2019-08-12T07:00:00"}}}
]
}
}
}
into url query. But I don' really know how to do this.
Thanks.
The Spring RestTemplate does not send your Body in a GET request, as a GET request should not contain a body but use query parameters instead. Read more on it here HTTP GET with request body
Therefore the Elasticsearch API allows also POST to send a query with a body. I would recommend this as your first solution:
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html
Both HTTP GET and HTTP POST can be used to execute search with body. Since not all clients support GET with body, POST is allowed as well.
If you really want to use a GET request from Spring RestTemplate to transfer a body you need to replace and extend the RequestFactory. You can find an example for exactly your case in this blog post.

REST api for field validation

I have to create a couple of web services for validating possible values of given fields. I'm contemplating having something like:
POST /entity/fieldName body { fieldValues }
where the POST will return 400 (Bad request) if the arguments are invalid and 422 (Unprocessable entity) otherwise. However I do not really like the 422 response part very much since it makes the request always return an error. On the other hand since I'm only doing validation and this is a POST I don't want to actually create a new resource on the server (i.e. return 200). Is there another HTTP method / API endpoint that is better suit for this? For what it's worth I will be checking that the entity field with <fieldName> has its value in a given range.
If all you do is validating, then I think you should send 422 by validation error and 200 by validation success. The POST does not mean you have to always create a new entity.
The action performed by the POST method might not result in a
resource that can be identified by a URI. In this case, either 200
(OK) or 204 (No Content) is the appropriate response status, depending
on whether or not the response includes an entity that describes the
result.
If a resource has been created on the origin server, the response
SHOULD be 201 (Created) and contain an entity which describes the
status of the request and refers to the new resource, and a Location
header (see section 14.30).
https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
I'm prefer google's api error response style.
So my service sends error response as json or xml and 400 Bad request error code:
{
"status": "INVALID_REQUEST",
"type": "ERROR_MSG",
"data": {
"request": "/v2/data?age=23d",
"errors": [
"age: not a number"
]
},
"time": -1
}
otherwise 200 and corresponding message

Comparing two JSON to make sure Key of first json is present in other one

I am writing here to get some clue regarding the problem I'm facing.
I am actually writing a service that will send text messages using some third party API. I've lots of message templates (static text and placeholders for dynamic content) that needs to be sent out and this service will be called from multiple modules with-in my application.
What I've planned is to store message templates in database and once any module require to send text message it will call my messaging service and pass data require to fill up the placeholders for a particular template.
I am saving my templates in database as follows:
{
"data": {
"message": "[GREETING], this is the test message sent on [DATE].",
"constant1": "",
"constant2": ""
},
"metadata": {
"data": {
"message": {
"[GREETING]": "required",
"[DATE]": "required"
},
"constant1": "required",
"constant2": "required",
"constant3": "optional"
}
}
}
data is the actual object I want eventually to pass messaging api and metadata is basically the constants and variables that are required/optional to complete data object.
and the data I'm receiving from other modules that are calling my service is:
{
"[GREETING]": "Dear John Doe",
"[DATE]": "28 February",
"data": {
"constant1": 982042,
"constant2": [64238, 64239]
}
}
So the issue is, I've to verify that all the required constant that are set required in templates metadata should be present the the json I'm receiving while my service is being called. I'm bit confused here of how I can compare the keys of data with template to make sure all the required data of template is sent by the module that has just called my service.
Can someone give me a clue if it's even possible in java ?
p.s: I just want some guidance or clue.
Thanks
Update: if someone have better and neat suggestion in achieving what I want to achieve in above mentioned scenario, please share I would really appreciate that.
Update2: Clarification of what I actually want to achieve: I've a JSON template in which I have a metadata field that tells me which parameters are required to fill up this specific template. So upon receiving call to my service, I've to first check that required parameters (set in metadata of templates) should be there in API request body. Hope that clears my requirements now.

Spring MVC handle multiple REST commands in a single HTTP request

I want to be able to generically handle a mass of commands as a single POST request represented as a map of URL => Body, that processes each command via its matching RequestMapping and returns a map of URL => Response.
Request:
{
"/api/things/34?huh=wat": {
"method": "GET"
},
"/api/dogs": {
"method": "POST",
"body": /* some dog-esque json */
}
}
Response:
{
"/api/things/34?huh=wat": {
"response": /* thing-esque json */
},
"/api/dogs": {
"response": /* some error json */
}
}
I am not concerned too much with the shape of the request/response objects, I just don't know how to handle this in Spring.
It sounds like the client should be splitting the individual requests up and sending them one at at a time. Think about it this way, what happens if the POST succeeds but the GET returns a 500 server error? Do you take the status of the whole request to be 500? And what about the POST, does it now need to be rolled back?

Categories