问题
Let's say someone developed rest api that returns data in json format but he didn't set response Content-Type
to application/json
but text/html
.
Now I have test written in REST Assured:
given()
.param("username", username)
.param("password", password)
.when()
.get("/authenticate")
.then()
.statusCode(200)
.body("user.id" , hasItem(20));
but it doesn't work. I logged out response body and and that's what I get:
<html>
<body>{"key":"752E7A74E8F3999BE9EFE3EA0E0DF320","user":{"id":20,"firstName":"K1","lastName":"K1","role":"ROLE_CUSTOMER","phoneNumber":"888888888"},"expirationDate":"2016-08-10T13:52:50+02:00"}</body>
</html>
and the error:
FAILED: test_login_as_valid_customer("888888888", "3432")
java.lang.AssertionError: 1 expectation failed.
JSON path key doesn't match.
Expected: 20
Actual:
Between body tags there is my expected json but where did html tags come from? I cant't see them in response when I test api method in Postman or Paw or even in web browser (since it is simple GET with url params).
I suspect I get error "JSON path key doesn't match." because of those tags.
回答1:
3 years passed from the original question, I'm having the same issue and here's what I've got.
1 - logging issue
Wrapping the response body into html tags is a work of io.restassured.internal.support.Prettifier
class.
You can disable it the following way.
RestAssured.requestSpecification.expect()
.log().body(false) // `shouldPrettyPrint` parameter set to false
But it affects only logging, not actual response body.
2 - matching issue
Assertions on response body mind it's content-type. If some API gives invalid headers and there's no way to fix it on the server side, you can work it around on the client side. In case of RestAssured, it can be done with a filter:
static final Filter FORCE_JSON_RESPONSE_BODY = (reqSpec, respSpec, ctx) -> {
Response response = ctx.next(reqSpec, respSpec);
((RestAssuredResponseOptionsImpl) response).setContentType("application/json");
return response;
};
// globally
RestAssured.filters(FORCE_JSON_RESPONSE_BODY);
// or per request
Response response = RestAssured
.given()
.filters(FORCE_JSON_RESPONSE_BODY)
.get("something")
回答2:
You can do:
import io.restassured.http.ContentType;
RestAssured.given()
.header("Accept", "application/json")
.when()
.get(endpoint)
.then()
.statusCode(200)
.contentType(ContentType.JSON);
The above header provides the header parameter. Once, the request is processed it checks for the status code 200 and the content type as JSON.
回答3:
Depending on how your endpoints are implemented, the format of the data returned may depend on the value of Accept
header the client sent. So check exactly what headers you are sending when you test with Postman and in your RESTAssured test — they may well differ, and your endpoint might be returning HTML if you do not explicitly specify Accept: application/json
in your request.
回答4:
The html tags come from the Content-Type being text/html, so the json data is recognised as text and is wrapped in the body of an html. If you inspect the text in the browser you will probably see the html tags.
回答5:
but where did html tags come from?
Someone added them manually, or written a rule on the server or client to add these. "Content-type" is a part of a header.
HTML and BODY are markup tags that are parts of document. If I remember correct these are not necessary in HTML5.
You have two options: 1) ask someone who added these to remove them. (It might be even yourself) 2) Use "no-lambda" style: "response = ", strip out tags from response and do your checks on the resulting json. Fore detail see https://github.com/rest-assured/rest-assured/wiki/usage#getting-response-data You ll need to add a step to strip out html tags via some string operation or html parser.
来源:https://stackoverflow.com/questions/38743055/java-rest-assured-response-body-with-content-type-text-html-with-injected-html