【问题标题】:java REST Assured response body with Content-Type: text/html with injected html tagsjava REST Assured response body with Content-Type: text/html with injection html tags
【发布时间】:2016-08-03 12:00:53
【问题描述】:

假设有人开发了rest api,它以json格式返回数据,但他没有将响应Content-Type设置为application/json而是text/html

现在我已经用 REST Assured 编写了测试:

    given()
    .param("username", username)
    .param("password", password)
.when()
    .get("/authenticate")
.then()
    .statusCode(200)
    .body("user.id" , hasItem(20));

但它不起作用。我注销了响应正文,这就是我得到的:

<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>

和错误:

FAILED: test_login_as_valid_customer("888888888", "3432")
java.lang.AssertionError: 1 expectation failed.
JSON path key doesn't match.
Expected: 20
  Actual:

在正文标签之间有我预期的 json,但 html 标签是从哪里来的?当我在 Postman 或 Paw 甚至网络浏览器中测试 api 方法时,我看不到它们的响应(因为它是带有 url 参数的简单 GET)。

我怀疑我收到错误“JSON 路径键不匹配”。因为那些标签。

【问题讨论】:

    标签: java json rest rest-assured


    【解决方案1】:

    从最初的问题过去了 3 年,我遇到了同样的问题,这就是我遇到的问题。

    1 - 日志记录问题

    将响应正文包装成 html 标签是 io.restassured.internal.support.Prettifier 类的工作。 您可以通过以下方式禁用它。

        RestAssured.requestSpecification.expect()
            .log().body(false) // `shouldPrettyPrint` parameter set to false
    

    但它只影响日志记录,而不影响实际的响应正文。

    2 - 匹配问题

    关于响应身体的断言是内容类型。如果某些 API 提供了无效的标头并且无法在服务器端修复它,您可以在客户端解决它。在 RestAssured 的情况下,可以使用过滤器来完成:

        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")
    

    【讨论】:

    • 请注意,RestAssured 文档github.com/rest-assured/rest-assured/wiki/Usage#filters 建议使用响应生成器来更改响应。此外,您可以使用 ContentType.JSON 常量而不是“application/json”文字
    • 当响应是 not json 和 not html 时,这段代码能正常工作吗?如果不是,那么我们如何处理这种情况?
    【解决方案2】:

    你可以这样做:

    import io.restassured.http.ContentType;
    
    RestAssured.given()
         .header("Accept", "application/json")
         .when()
         .get(endpoint)
         .then()
         .statusCode(200)
         .contentType(ContentType.JSON);
    

    上面的 header 提供了 header 参数。处理完请求后,它会检查状态代码 200 和内容类型是否为 JSON。

    【讨论】:

      【解决方案3】:

      根据您的端点的实现方式,返回的数据格式可能取决于客户端发送的Accept 标头的值。因此,在使用 Postman 进行测试时和在 RESTAssured 测试中准确检查您发送的标头 - 它们可能会有所不同,如果您未在请求中明确指定 Accept: application/json,您的端点可能会返回 HTML。

      【讨论】:

      • 在 Postman 中我没有指定 Accept 标头。当我在 RESTAssured 测试中尝试时 - given().accept(ContentType.JSON) 它仍然返回 text/html
      • 我只是尝试使用返回 Content-Type: application/json 的 api 执行类似的测试,它通过了。 json 中的目标变量已找到并正确提取以进行断言。
      【解决方案4】:

      html 标签来自于 Content-Type 为 text/html,因此 json 数据被识别为文本并被包裹在 html 的正文中。如果您在浏览器中检查文本,您可能会看到 html 标签。

      【讨论】:

      • 我在浏览器中检查了响应,没有html标签。
      猜你喜欢
      • 1970-01-01
      • 2020-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多