I'm looking at Spring REST Docs and wondering if it has the ability to interrogate #RestController methods to produce basic documentation describing a Rest API (methods, http method, parameters, response type)? I believe Springfox Spring/Swagger does that, and would be easier than having to write a test to get that basic info/documentation.
Also, since I don't want to run integration tests in a Production environment, is the Spring RestDocs approach to run your integration tests in a Test environment and then copy the generated docs/snippets into the war so it can be viewed in a Prod environment?
I'm looking at Spring REST Docs and wondering if it has the ability to interrogate #RestController methods to produce basic documentation describing a Rest API
Spring REST Docs is test-driven and deliberately doesn't take the approach of introspecting #RestController methods. You REST API documentation is describing HTTP requests and responses. By being test-driven and working with real or mocked HTTP requests and responses, REST Docs ensures that what you're documenting is what users of your API will be dealing with.
The problem with introspecting #RestController methods is that it's only one small piece of the puzzle. When an HTTP request is received it passes through filters, interceptors, HTTP message conversion etc before it reaches your controller. The same is true in reverse when a response is being sent. Without a complete understanding of everything that happens before your controller's called and everything that happens after your controller returns, the documentation is at risk of being inaccurate.
is the Spring RestDocs approach to run your integration tests in a Test environment and then copy the generated docs/snippets into the war so it can be viewed in a Prod environment
Correct. The documentation is generated once at build time and then typically served as static files from your application. Details of how to do this with Spring Boot are included in the documentation.
This approach has the advantage that none of the code that's involved in creating the documentation is running in production. That reduces your application's footprint, and avoids the possibility of the code that's generating the documentation from causing a problem in production. I believe you can take a similar approach with code-first Swagger tools but, in my experience, it's unusual for people to do so.
Swagger is best choice for me. You cannot do make docs with Spring Rest Docs without integration tests. It's good article reviews rest tools
Related
I'm developing a Spring Boot Web API, and I'm currently writing the required units tests.
I was wondering : Isn't writing the units tests (JUnit + Mockito) for the controllers sufficient ? Since the controllers are the entrypoint of my application and that all the logic that is implemented within the Service side is called from the exposed API, why do I need to write test for the Service side ?
First of all, if you write your tests to cover "required level of tests" or requirement to "have some tests at all" having the production implementation already done, it is slightly too late. In the majority of cases having tests first, based on your requirements, contract, use case or anything it more optimal approach. Nevertheless, I don't know your situation and the thing you're trying to implement, so treat it as a suggestion and move on to the key thing you are asking about.
Your JUnit (preferably 5) and Mockito tests, which probably use MockMvc are very good unit(-like) tests to cover web communication concerns such as: HTTP request types, content type, encoding, input and output parameters JSON (de)serialization, error handling, etc. They are best to test with the service layer mocked. Thanks to that you can easily cover a lot of web cases without the need to prepare data in a database, etc.
The core logic has to also be tested. Depending what it is, it might be feasible to test it in the unit way (the easiest to write, can cover a lot of - also corner - cases). It could be supplemented with some set of integration tests to verify that it works fine also in integration (Spring Beans, DB, etc.).
If desired, you may also write some E2E test from the web call via (real) HTTP requests through controllers, services to a database/datastore (if any), but I would limit it only to the most important scenarios to use it in your CI/CD pipeline to verify that a deployment finished successfully.
Disclaimer. I've found this approach useful in multiple situations, but definitely in some other circumstances it might be good to change the balance point to better apply testing.
I think you are probably getting confused between unit and Integration tests.
If you are using Mockito you are probably referring to unit tests wherein, the scope of the Test Class should be only the current class.
Any external method calls should be mocked.So in your case the service calls should be mocked in case you are writing unit test for your controller class.
Your Test Suite should contain
Junit for Controller-- To Test the interface contract points like HTTP Method, Request Parameters, Mandatory inputs, Valid Request Payloads.
Junit for all other classes including Service classes- This is to test your application classes core logic
Integration Test- Finally an integration test which can hit your controller endpoints with service classes and rest of the application code functionality.
recently i saw the blog post say that "for documentation purpose, we use mocking for service layer (in environment using spring rest doc)", so this post use annotation like spring's #MockBean to service layer object.
but i think, if i mock service layer -> spring rest doc always success to test because mocked service object always return intended result and spring rest doc test always receives same intended result from mocked service object.
so i think that is not right but,
i want to know about what is better or how you use service object with spring rest doc
pleas answer
Whether or not it's a good idea to mock the service layer when using Spring REST Docs is largely down to personal preference.
A possible disadvantage of mocking the service layer is that it may be possible for the documentation to get out of sync with the service's actual behaviour. This undermines REST Docs' ability to help you to keep your documentation and service in sync.
An advantage of mocking the service layer is that it can make it easier to document error scenarios or scenarios that would otherwise require quite a lot of setup. In the case of errors, I think you are better adopting a common approach across your whole API and making consistent use of standard HTTP error codes. If you do this, the need to document error responses for each endpoint in a service is reduced.
This leaves documenting more complex scenarios that require a lot of setup. In this case, limited use of mocks may be worthwhile but I would still aim to produce as much of your documentation as possible without relying on mocks.
Spring Data REST creates a CRUD web server with a discoverable API, so it seems it should be possible to write a generalized web client application for it. Is there such an application?
May be you are looking for a HAL browser
https://www.baeldung.com/spring-rest-hal
or
something like https://www.npmjs.com/package/angular-spring-data-rest
https://www.npmjs.com/package/angular4-hal
I hope you mean sample client stubs. Actually a web client cannot be generalized beyond the resources it has. That will not be quite meaningful.
You can try below with swagger. Using swagger here would be really convenient (over raml etc) since spring-data-rest generates swagger it self for you.
Take your swagger spec
Paste it at https://editor.swagger.io/.
Go Generate Client => Your favorite programming language.
Then it will generate sample client stubs for you in the language you have selected.
I think this should be the far most generalized point that makes sense.
-Addition-
The primary problem spring-data-rest has solved is abstracting out all the common functionalities attached to controller (ex: response/request mapping etc) and making them readily available and configurable, so that the developer no longer needs to re-invent/duplicate them every time when they are coding a new endpoint.
So as you have suggested generating client-stubs is completely out of spring-data-rest scope. Please read the documentation for more info.
I have seen this Spring REST Docs - video
We are doing Spring boot projects and are using springfox library for generating the Swagger-ui and swagger documentation as outlined here
We like what Spring Rest docs can do for generating REST API documentation and the fact that we don't have to add swagger annotations like #ApiResponse or #ApiOperation in our Controller code. And also the fact that the documentation now lives with the code.
But if go with Spring Rest docs, we will miss out on the Swagger-UI that gets automatically generated for our API (when we use swagger integration).
Is it possible for Spring REST docs to generate a test UI like Swagger UI.
That pretty directly goes against the design idea and intention of Spring REST Docs. One of the main goals of it is that the docs are tied to unit tests so you know your documentation is rock solid even when you make logic or signature changes in your REST contract.
Also as the video you linked to provided a number of examples of how automated docs generation produces a lot of undesirable un-intended output.
So its a choice of do more work to get much better docs, or do the fully automated option to save time and get workable, but lower quality docs. It is what ever your priority is.
This project generates an OpenAPI specification from Spring REST Docs.
https://github.com/ePages-de/restdocs-api-spec
I'm working on a client code that interfaces with a remote REST service but I'm not exactly sure how to go about mocking the service for my automated tests. I've seen this guide on how to test GORM REST, which I thought I could use as reference, but it looks like it requires a Grails environment to run fine. I'm pretty sure I can incorporate Spring Test into my Groovy project but there are other things I'm not clear about. In particular, I'm not sure how to make the following lines from the link work on plain Groovy project:
RestTemplate rt = Book.restBuilder.restTemplate
final MockRestServiceServer mockServer = MockRestServiceServer.createServer(rt)
In the given guide, Book is a Grails domain class. in the first line above, it refers to a restBuilder property, and I don't know where it came from. The main concern here, I guess, is getting an instance of RestTemplate which I'm not very familiar with.
To be clear, I don't have to stick with this approach. Setting up RestTemplate looks a little complicated without the Grails environment, so if there are other tools that would allow me to mock REST services more easily in a plain Groovy project, I'd be happy to consider them.