【问题标题】:Spring REST Docs: how to replace parametersSpring REST Docs:如何替换参数
【发布时间】:2015-10-22 12:52:19
【问题描述】:

在我的单元测试中我们发现

this.mockMvc
  .perform(post("/authenticate")
    .contentType(MediaType.APPLICATION_FORM_URLENCODED)
    .param("username", "user@example.com")
    .param("password", "superSecretPassword"))
  .andExpect(status().isOk())
  .andDo(document("preprocessed-request",
    preprocessRequest(replacePattern(Pattern.compile("superSecretPassword"), "XXX"))));

参见。 Spring REST Docs documentation

这会生成带有内容的build/generated-snippets/preprocessed-request/http-request.adoc

[source,http]
----
POST /authenticate HTTP/1.1
Content-Type: application/x-www-form-urlencoded

username=user%40example.com&password=superSecretPassword
----

但我希望密码会因为 replacePattern() 而被屏蔽:

[source,http]
----
POST /authenticate HTTP/1.1
Content-Type: application/x-www-form-urlencoded

username=user%40example.com&password=XXX
----

我能做什么?

【问题讨论】:

    标签: java spring spring-mvc spring-restdocs


    【解决方案1】:

    由于 MockMvc 如何处理请求参数的不幸副作用,模式替换无效。 replacePattern 作用于内容,即请求的正文,但 MockMvc 实际上并没有在正文中包含表单编码的参数。

    Spring REST Docs 在生成 sn-ps 时足够聪明地处理这个问题,例如对于编码为POST 的表单URL 请求,它会查看参数以确定请求的正文应该是什么。应用 replacePattern 时,它不会应用这些相同的智能。

    您仍然可以使用更改参数映射的自己的OperationPreprocessor 来屏蔽密码。例如:

    private OperationPreprocessor maskPassword() {
        return new PasswordMaskingPreprocessor();
    }
    
    private static class PasswordMaskingPreprocessor implements OperationPreprocessor {
    
        @Override
        public OperationRequest preprocess(OperationRequest request) {
            Parameters parameters = new Parameters();
            parameters.putAll(request.getParameters());
            parameters.set("password", "XXX");
            return new OperationRequestFactory().create(request.getUri(),
                    request.getMethod(), request.getContent(), request.getHeaders(),
                    parameters, request.getParts());
        }
    
        @Override
        public OperationResponse preprocess(OperationResponse response) {
            return response;
        }
    
    }
    

    然后您可以使用这个新的预处理器代替replacePattern

    this.mockMvc
      .perform(post("/authenticate")
        .contentType(MediaType.APPLICATION_FORM_URLENCODED)
        .param("username", "user@example.com")
        .param("password", "superSecretPassword"))
      .andExpect(status().isOk())
      .andDo(document("preprocessed-request",
        preprocessRequest(maskPassword())));
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-23
    • 1970-01-01
    • 1970-01-01
    • 2014-11-22
    相关资源
    最近更新 更多