Spring rest docs: Error when creating custom TemplateSnippet

佐手、 提交于 2021-01-29 05:26:01

问题


I want to create a custom HttRequestSnippet with spring rest docs.

Because I want the url to be shown as /accounts/{id} and not /accounts/1 , I have to create a custom snippet class.

I tried two approaches:

  1. I tried to get this going in general. Therefore I pass the uri as a parameter to the class.

    public class CustomHttpRequestSnippet extends TemplatedSnippet {
    
     public CustomHttpRequestSnippet(String uri) {
         super("custom", Collections.singletonMap("path",uri));
     }
    
     @Override
     protected Map<String, Object> createModel(Operation operation) {
         Map<String, Object> model = new HashMap<>();
         model.put("custom-path", removeQueryStringIfPresent(extractUrlTemplate(operation)));
         return model;
     }
    

    }

and in my test I did:

CustomHttpRequestSnippet customHttpRequestSnippet = new CustomHttpRequestSnippet("/accounts/{userId}");

and included it to the document(..

.andDo(document("{methodName}",
                    preprocessRequest(prettyPrint()),
                    preprocessResponse(prettyPrint()),
                    pathParameters(
                            parameterWithName("userId").description("userId of the requested user.")
                    ),
                    customHttpRequestSnippet,

This results in an error:

org.springframework.restdocs.mustache.MustacheException$Context: No method or field with name 'method' on line 3

    at org.springframework.restdocs.mustache.Template.checkForMissing(Template.java:270)
    at org.springframework.restdocs.mustache.Template.getValue(Template.java:178)
    at org.springframework.restdocs.mustache.Template.getValueOrDefault(Template.java:223)
    at org.springframework.restdocs.mustache.Mustache$VariableSegment.execute(Mustache.java:787)
    at org.springframework.restdocs.mustache.Template.executeSegs(Template.java:114)
    at org.springframework.restdocs.mustache.Template.execute(Template.java:91)
    at org.springframework.restdocs.mustache.Template.execute(Template.java:82)
    at org.springframework.restdocs.templates.mustache.MustacheTemplate.render(MustacheTemplate.java:62)
    at org.springframework.restdocs.snippet.TemplatedSnippet.document(TemplatedSnippet.java:82)
    at org.springframework.restdocs.generate.RestDocumentationGenerator.handle(RestDocumentationGenerator.java:191)
    at org.springframework.restdocs.mockmvc.RestDocumentationResultHandler.handle(RestDocumentationResultHandler.java:52)
    at org.springframework.test.web.servlet.MockMvc$1.andDo(MockMvc.java:201)

in addition, the createModel is never called. Overall, this would be a quick fix solution to me. I would prefer, that the custom method is treated as the standard HttpRequestSnippet class. I mean that I would prefer to be able to use the standard request ( OperationRequest ) and put some additional information to it. As a result, I would write a custom .snippet to document the parts I need.

The second apprach I tried was to extend the HttpRequestSnippet.class and use the methos of the PathParametersSnippet class, because here the path is processed like I need it.

    public class CustomHttpRequest extends HttpRequestSnippet {


    public CustomHttpRequest(Map<String, Object> attributes) {
        super(attributes);
    }

    @Override
    protected Map<String, Object> createModel(Operation operation) {
        Map<String, Object> model = super.createModel(operation);
        model.put("custom-path", removeQueryStringIfPresent(extractUrlTemplate(operation)));
        return model;
    }

    private String removeQueryStringIfPresent(String urlTemplate) {
        int index = urlTemplate.indexOf('?');
        if (index == -1) {
            return urlTemplate;
        }
        return urlTemplate.substring(0, index);
    }

    private String extractUrlTemplate(Operation operation) {
        String urlTemplate = (String) operation.getAttributes()
                .get(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE);
        Assert.notNull(urlTemplate, "urlTemplate not found. If you are using MockMvc did "
                + "you use RestDocumentationRequestBuilders to build the request?");
        return urlTemplate;
    }
}

This results in no error but the Constructor and the createModel function are never called.

As far as I understand, I have to trigger this from within the document(... section in my test but I don't know how. It seems like the trigger of the standard HttpRequestSnippet class is done somewhere within the rest docs code. Also, the .adoc file is generated automatically or do I have to provide one with the additional parameters?

Can one tell me what I got to change to get this work or is my approach wrong in general?

来源:https://stackoverflow.com/questions/65680019/spring-rest-docs-error-when-creating-custom-templatesnippet

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!