I am trying to create a test to validate the response of a JSON Post is as expected.
I am trying to test the POST of a JSON message body to a URL which is turn then sends a text message and if successful it sends a response that it was successful again in JSON format.
My test is as follows
public void simpleTest() {
String myJson = "{\"phoneNumber\":\"353837986524\", \"messageContent\":\"test\"}";
given()
.port(31111) // port number
.header("Content-Type", "application/json")
.body(myJson)
.when()
.post("/testenvironment/text/send")
.then().assertThat()
.body("message", equalTo("{\"resultMessage\":\"Message accepted\"}"));
}
But seem to be getting this exception
java.lang.IllegalStateException: You can either send form parameters
OR body content in POST, not both!
And I'm not sure what the issue is?
Restassured is failing to parse Json as per the stack trace. I use org.json jar, which is more elegant way to handle big json inputs. There are other implementations of json handling in java, which can be used based on your preference.
Coming to your code:
public void simpleTest() {
// use org.json JSONObject to define your json
JSONObject jsonObj = new JSONObject()
.put("phoneNumber","353837986524")
.put("messageContent","test");
given()
.port(31111) // port number
.contentType("application/json") //another way to specify content type
.body(jsonObj.toString()) // use jsonObj toString method
.when()
.post("/testenvironment/text/send")
.then()
.assertThat()
.body("message", equalTo("{\"resultMessage\":\"Message accepted\"}"));
}
Also, I didnt find what the output of the rest service in the question. For example it is returning a a json {"resultMessage":"Message accepted"} you should be validating the response in the following way:
...
.body("resultMessage",equalTo("Message accepted"));
Try changing the mimeType to a header instead of a parameter.
And based on the information you shared I think what you need is the Content-Type header, not mimeType.
Related
I know how to extract a value from Response body and also how to validate a field from response body, but what the problem is
void postRequest() {
Response id = given()
.auth()
.preemptive()
.basic(username,password)
.contentType(ContentType.JSON)
.body(----- some JSON body ------)
.when()
.post(baseurl+"postRequest")
.then()
.contentType(ContentType.JSON)
.extract()
.path("id")
;
}
with this, I can extract the value that I want to and saved it into a variable "id" and use it for further API requests.
response
.then()
.log().ifValidationFails(LogDetail.ALL, true) # I NEED TO PRINT REQUEST PARAMS TOO IF IT FAILS
.assertThat()
.statusCode(200)
;
If I did the above approach, I couldn't get to validate the response body since we didn't save the response to a variable.
I want to do both in one go. Also, I tried the opposite too, where I validated the response body first, but I couldn't save the "id" since we can't convert ValidatableResponse to Response or vice versa. I do not want to print the request params unless the request fails.
Help me find a way with this.
As far as I understand, you want both: validate response and extract value (for other API) in one chain command. This is example:
int id = given().post()
.then()
.log().ifValidationFails()
.assertThat()
.contentType(ContentType.JSON)
.statusCode(200)
.body("id", equalTo("test"))
.extract()
.response()
.path("id");
In the example below I am trying to send a request with a JSON body to a mock REST API. The problem is when I try to get the response which should be JSON it returns an empty or null string. Why is this the case?
Note: when I add the .peek() to the response object it will print the expected results for me. But what I want is to capture those results in the response object. Also this one happens with the JSON string sent is bad format. I am expecting the bad results so that I can assert on them.
String jsonBody = ...
MockMvcRequestSpecification request = given()
.header("Content-Type", this.contentType)
.body(jsonBody);
ResponseOptions response = given().spec(request)
.post(this.apiUrlPath);
//This works, I can see the status code
assertThat(response.statusCode(), Matchers.equalTo(400));
//This doesn't print anything, the body is always empty
//json response is expected explaining why the request failed
//response.peek() will print what I am expecting
System.out.println(response.getBody().asString());
I'm trying to do a HTTP DELETE request with body with Spring RestTemplate via exchange method but I always get a 400 Bad Request like this question. With JavaScript and other tools it is posible to make this API call with DELETE.
I know java <1.8 doesent support DELETE with body, but with 1.8 it should be able: see here. I'm using spring-web-4.2.6.RELEASE with jdk 1.8 so I think there must be a way.
My code:
public DealResponse closePosition(DealCloseRequest dealCloseRequest) {
try {
ObjectMapper mapper = new ObjectMapper();
//Object to JSON in String
String jsonInString = mapper.writeValueAsString(dealCloseRequest);
HttpEntity<String> entity = new HttpEntity<String>(jsonInString, this.headers);
//execute request
ResponseEntity<DealResponse> response = restTemplate.exchange("https://" + this.domain + "/gateway/deal/positions/otc", HttpMethod.DELETE, entity, DealResponse.class);
//return filled DealResponse object
return response.getBody();
} catch (JsonProcessingException e) {
this.logger.warn("could not close Position because: "+e);
return null;
}
}
Error message:
org.springframework.web.client.HttpClientErrorException: 400 Bad Request
Does anyone know a way to do this with spring restTemplate?
HTTP DELETE request with body works fine with rest template for Spring 4.2 release. There could be some issue with request body you are sending to your service. Can you check "jsonInString" if it is forming correct json payload.Check the headers as well for "application/json" type. You can verify your service using Postman by sending DELETE request.
I want to write a JUnit class for a REST endpoint.
This is my REST method. It works fine.
#POST
#Path("create")
#Produces(APPLICATION_JSON)
public String create(#QueryParam("parentId") String parentId, #QueryParam("name") String name) {
//do sth.
return "{\"status\": \"SUCCESS\"}";
}
Now my JUnit test looks like that, which doesn't work, because I don't know how to POST my data in the right way:
#Test
public void testCreate() {
Client client = ClientBuilder.newClient();
WebTarget wt = client.target(REST_MENU_URL + "create");
String queryParams = "parentId=1&name=NEW_JUnit_NEW";
// In the line below, I want to POST my query parameters, but I do it wrong
Response response = wt.request().post(Entity.entity(queryParams, APPLICATION_JSON), Response.class);
// The response has a 500, because the query parameters are all NULL!
assertEquals("Http code should be 200", 200, response.getStatus());
}
So how do I have to change the line with the 'Response' to make it work?
The problem is, that the query parameters (parentId and name) don't get transmitted (response = wt.request().post(...)).
I tried to POST form parameters too, but no success here either. Just like that:
Form form =new Form().param("parentId", "4").param("name", "NEW_JUnit_NEW");
Response response = wt.request().post(Entity.entity(form, APPLICATION_JSON), Response.class);
Thanks,
Bernhard
Check out the Jersey Client documentation, in particular section 5.3.4 on targeting resources.
Query parameters form a part of the URI of the resource, they're not part of the body of the document posted to the resource. You're seeing null in your resource because you're not filling in the query parameters in the URI, you're posting them as the body. You need to tell Jersey to put them in the URI...
WebTarget wt = client.target(REST_MENU_URL + "create").queryParam("parentId", 1).queryParam("name", "NEW_JUnit_NEW");
You'll also need to ensure that your POST request sets the Accept header to allow application/json (by calling the accept(...) method after calling request()) and you're going to need to construct some kind of Entity to pass to the post(...) method - the problem here is that your resource is not consuming the entity body but the client API expects you to send something - this is a code smell which suggests your API is not particularly ReSTful. You can probably get away with some kind of empty body constructed from an empty string. It should look a bit like this...
Response response = wt.request().accept(MediaType.APPLICATION_JSON).post(Entity.text(""))
Alternatively, you could look into converting your API so that it accepts a JSON document and move the query parameters into that document.
I am using Play framework 2.2.3. I want to respond to invalid JSON requests with a JSON response saying response type is invalid JSON like
{"message": "invalid json"}
but Play by default sends html data. I am using
#BodyParser.Of(BodyParser.Json.class)
annotation for my action method in the controller class. How do I send a JSON response instead of the default html response?
Play automaticaly sets content type depending on type of returned data, so use valid JSON object, you don't need to use #BodyParser for that, badRequest additionally sets response status to 400
public static Result someAction() {
ObjectNode answerObj = Json.newObject();
answerObj.put("message", "invalid json");
return badRequest(answerObj);
}