Java REST API GET test - java

im wondering how to test GET given below. I don't have much experience with testing so would be glad if some 1 could show me proper approach or comment what should i do better.
#Path("/some")
public class SomeApi {
#Inject
SomeLogic someLogic;
#GET
#Produces({"application/json;charset=utf-8","application/json"})
#RolesAllowed("ek_external")
public Response getSome(#QueryParam("id") Long id, #QueryParam("name") String name, #Min(0) #DefaultValue("0") #QueryParam("offset") Integer offset, #Min(1) #Max(50) #DefaultValue("20") #QueryParam("limit") Integer limit, #Context SecurityContext securityContext) {
return someLogic.getSome(id, name, offset, limit, securityContext);
}
}
This is my GET. Im not sure how to handle all these QueryParams and annotated args.
Im trying something like this
#QuarkusTest
public class SomeApiTest {
#Test
public void testGetSome() {
given()
.when().get("/some")
.then()
.statusCode(200)
.body()
}
}
i ll be glad for showing me which way to go :)

The example in the documentation here: https://quarkus.io/guides/getting-started-testing#recap-of-http-based-testing-in-jvm-mode suggests the only thing missing might be setting the body... ...(200).body(is(someBody)).
The example given here: https://quarkus.io/guides/getting-started-testing#restassured also looks relevant.
Also ensure you provide #TestConfiguration so that when you #Inject the class for SomeLogic, it is not null.

Related

How to do post request on a method returns integer

in the below example, I am trying to know how in he below code, i am trying to perform POST request given the method initVar ().
I tried to do the post request as follows:
http://localhost:8080/root/initVar/id/2->error
http://localhost:8080/root/initVar/id?2->error
but it does not work when i return Int data type form the method.
please let me know how to fix this error.
please note that this method return Int
code:
#RestController
#RequestMapping("root")
class Controller1 {
val sayHiLazy by lazy {
"hi from get"
}
#GetMapping(value = "/sayHi")
#ResponseBody
fun sayHi() : String {
return sayHiLazy
}
#PostMapping("/initVar/id")
#ResponseBody
fun initVar(#PathVariable id : Int) : Int {
return 11
}
}to use spring annotation with koltin in intellij. i used spring annotation with java projects in intellij. but for koltin, it does not work.
in the below example, HelloController is underlined with red and i recived the following werror:
classes annotated with #Configurations cannto be implicily subclassed and must be final
please let me know how to fi
Controller1
#SpringBootConfiguration
#RequestMapping("/app")
public class HelloController {
#RequestMapping(value = "/hello")
fun SayHello(): String {
return "success"
}
}
If You want to use #PathVariable, You have to do something like this:
#RequestMapping(value="/stuff/{id}")
#ResponseBody
public String doStuff(#PathVariable("id") int id){
return "id="+id;
}
You usually write POST method without variables at the end. For such scenarios You should use PUT - https://restfulapi.net/rest-put-vs-post/
I'm not sure if You can return plain integer as a response, but You could optionally wrap your integer into String - String.valuOf(id);
Regards

Spring MVC. How Pageable actually works?

Please help me to figure out how Spring parses HTTP GET parameters from the request into the Pageable-suited object without any additional annotations like #RequestBody, #RequestParam, etc.
So, I send a request that looks like this:
GET /questions?page=0&size=2&sort=createdAt,desc.
As an argument of the getQuestions method I get an object consisted of three fields like page, size, sort. But, how this magic actually works?
#RestController
public class QuestionController {
#Autowired
private QuestionRepository questionRepository;
#GetMapping("/questions")
public Page<Question> getQuestions(Pageable pageable) {
return questionRepository.findAll(pageable);
}
#PostMapping("/questions")
public Question createQuestion(#Valid #RequestBody Question question) {
return questionRepository.save(question);
}
// other restful methods
}

Error 404 accessing to a SubResource in a JAX-RS Jersey

I have these 2 resources
#Path("/orders")
public class OrderResource {
#GET
#Path("/{id}")
#Produces(MediaType.APPLICATION_JSON)
public Response getOrder(#PathParam("id") String orderid)
throws JSONException {
Order order = db.getOrder(orderid);
return Response.status(Status.OK).entity(order).build();
}
#GET
#Path("/{orderid}/products")
public ProductResource getProducts() {
return new ProductResource();
}
}
#Path("/")
public class ProductResource {
#GET
#Path("/{productid}")
#Produces(MediaType.APPLICATION_JSON)
public Response getProduct(#PathParam("orderid") String orderid, #PathParam("productid") String productid) throws JSONException {
Product product = db.getProduct(productid);
return Response.status(Status.OK).entity(product).build();
}
}
I get a successful output when I do this:
http://localhost:8080/testApp/api/orders/O101
I can see the collection of the products linked to the order in the output so I copied the id and tried this
http://localhost:8080/testApp/api/orders/O101/products/P101
But I always get a 404 error. Why? How can I solve this?
This is my config in the web.xml
<servlet-mapping>
<servlet-name>TestApp</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
EDIT
Thank you so much for your answers. Woke up this morning tired to test it with no success.
I tried your suggestions, but still get 404.
#Path("/orders")
public class OrderResource {
#GET
#Path("/{id}")
#Produces(MediaType.APPLICATION_JSON)
public Response getOrder(#PathParam("id") String orderid)
throws JSONException {
Order order = db.getOrder(orderid);
return Response.status(Status.OK).entity(order).build();
}
#GET
#Path("/{orderid}/products") //Here I added after products /{productID} which gives me an empty JSON. Never reach the method from the subresource.
public ProductResource getProducts() {
return new ProductResource();
}
}
public class ProductResource {
#Path("/{productid}") //Here I tried to remove the slash also.
#Produces(MediaType.APPLICATION_JSON)
public Response getProduct(#PathParam("orderid") String orderid, #PathParam("productid") String productid) throws JSONException {
Product product = db.getProduct(productid);
return Response.status(Status.OK).entity(product).build();
}
}
The problem is the #GET on the getProducts. A sub-resource locator is defined as a method with a #Path and which has no #METHOD. If you think about it, it makes perfect sense, as the there can be more than say just a #GET in the sub-resource class. So remove the #GET, and it should work. Leaving it would cause the method to not be a sub-resource locator, and it would behave like a normal resource method.
Aside from that, what others have suggested about the #Path("/") is not the cause of the problem, but it is a problem. What this does is cause Jersey to also register the ProductsResource as a root resource. So would be able to access /api/1234, since it is mapped to /. You probably don't want this. So you should remove the #Path("/") from the ProductsResource.
Sub-resources shouldn't be annotated with #Path on class level and they need to be registered with the JAX-RS runtinme.
Just remove the #Path annotation.
In your case, the problem seems to be the annotation #Path in your sub-resource. When defining a sub-resource, it should not be annotated at the class level with #Path. Also in your ProductResource, try removing the '/' from #Path("/{productid}") as it should be referenced from the context of the parent(OrderResource) and should not exists as an individual instance.
Thanks

JAX-RS sub resource #PathParam value does not match any #Path annotation template parameters of the java method and its enclosing java type

I have a class as a sub resource and when ran, everything works with no errors except for eclipse show red underline, how can I make eclipse "know" that the parent #Path is part of it.
ex.
in MessageResouce
#Path("/{messageId}/comments")
public CommentResource getCommentResource() {
return new CommentResource();
}
and in CommentResource
#Path("/") // optional for subresources
#Produces(MediaType.APPLICATION_XML)
#Consumes(MediaType.APPLICATION_XML)
public class CommentResource {
private CommentService commentService = new CommentService();
#GET
public List<Comment> getAllComments(#PathParam("messageId") long messageId) {
return commentService.getAllComments(messageId);
}
#POST
public Comment addMessage(#PathParam("messageId") long messageId,
Comment comment) {
return commentService.addComment(messageId, comment);
}
#PUT
#Path("/{commentId}")
public Comment updateMessage(#PathParam("messageId") long messageId,
#PathParam("commentId") long commentId, Comment comment) {
comment.setId(commentId);
return commentService.updateComment(messageId, comment);
}
#GET
#Path("/{commentId}")
public String test2(#PathParam("messageId") long messageId,
#PathParam("commentId") long commentId) { // messageId still gets
// passed from parent
// resource
return "Method return commment id: " + commentId + " and messageId: "
+ messageId;
}
#DELETE
#Path("/{commentId}")
public void deleteComment(#PathParam("messageId") long messageId,
#PathParam("commentId") long commentId) {
commentService.removeComment(messageId, commentId);
}
}
All the messageId path parameters are underlined with red with error but everything runs fine, it's annoying to see that there and I don't want anyone that might look at my code to freak out.
Thanks
I had the same problem but I resolved it by going to Preferences -> JAX-RS -> JAX-RS Validator -> JAX-RS Resource Methods and I check Unbound #PathParam annotation value as a warning or ignore (default was error). In case of ignore you will no longer see that message. From what I've read there might be something which has to do with the JAX-RS validation. I'm using JAX-RS 1.1 with Jersey 1.19 (not sure if in JAX-RS 2.0 you would have the same behavior).
In my experience, the JAX-RS validation in Eclipse/JBoss Developer Studio, stumbles when multiple annotated HTTP method functions are included in the same injected class. For instance, a single #GET method sets off no alarms, but adding a #POST method makes the validator unable to accurately detect the bindings between the various #PathParam and #Path statements.
It's annoying, but does not negatively impact code compilation or execution.
As Corina explains, the only real option is to edit the IDE preferences to downgrade the severity of the exception. I choose "warning" rather than "ignore", so as not to completely suppress any legitimate errors.
I had this kind of problem because I used the wrong import javax.websocket.server.PathParam; for my #PathParam. My API's test worked but JAXRS was not happy with it. Using javax.ws.rs.PathParam; can fix your problem.
you need to put your PathParam in the #Path(), wrapped in { }
like this
#POST
#Path("/availabilityForTopic/{idTopic}")
public Response addUserToAvailabilityForTopicList(#HeaderParam("token") String token, #PathParam("idTopic") int idTopic)

Error:param #param is always null

I have a problem with Jersey and Grizzly. The problem could be very basic but I am struggling to solve it. The idea is that I am creating an exercise application that needs to store books. Everything seems to be alright but it does not work as expected. Here is the source code:
#Path("/books")
public class BooksResource
{
private BookDao bookDao= new BookDao();
#GET
#Produces(MediaType.APPLICATION_JSON)
public Collection<Book> getBooks()
{
return (bookDao.getBooks());
}
#Path("/{id}")
#GET
#Produces(MediaType.APPLICATION_JSON)
public Book getBook(#PathParam("id")String id)
{
Book book = bookDao.getBook(id);
return (book);
}
As can be observed, the path /books is working perfectly but the problem is that id is always null and it shouldn't be. Does anyone know where the problem comes from?
Try removing "/" from the path and it should work.
From
#Path("/{id}")
To
#Path("{id}")

Categories

Resources