Spring mvc controller test + Json response error - spring

I have in my spring mvc test controller:
#Test
public void consultaPorIdJson() throws Exception{
mockMvc.perform(get("/timesheet/consultaporidjson/{id}", 1L))
.andExpect(status().isOk())
.andExpect(content().contentType(TestSupport.APPLICATION_JSON_UTF8))
.andExpect(content().string("{\"id\":1,\"latitude\":\"30.448660206791608\",\"longitude\":\"-44.29684999999995\"}"));
When I trying to run my test I get an error:
java.lang.IllegalStateException: Cannot set error status - response is already committed
I think that is about 2k (I think) of response, but I don't know what must I do to fix it :-(

Does the url works outside of your test? I doubt it does not work as the error suggests you have issue in your implementation where the code is trying to change the status when something is already written in the response.

Related

How can I test my controller for throwing an exception in Kotlin?

So I have a controller with one GET method. I need to test it. When I write in URL request with incorrect iso code of the country, it throws me back a custom exception. So how can I test it?
So here 'UA' is incorrect argument
#Test
fun check_for_incorrect_iso_code() {
mockMvc.perform(get("/countries/UA"))
.andDo(print())
.andExpect(status().is4xxClientError)
}
Test is working, but I need to extend it and check if it throws my custom exception - 'InvalidIsoCodeException' for example.
Thanks for the answer.
Your Java code is throwing an InvalidIsoCodeException but your server/controller cannot throw exceptions. Instead it sends back an HTTP response to the client. The InvalidIsoCodeException is mapped by Spring to a specific response. You're already checking the status of the response with .andExpect(status().is4xxClientError()). You can also verify the body of the response if you want to be more specific.
If you want to test for the exception then you have to test your controller like a normal Java class without MockMVC.

How to log 415 errors in Spring

My service is currently experiencing 415 errors, but I'm not getting any logs to find out what errors they are.
Will I be able to add logging in some kind of filter so that I can know what's going on?
#RequiresHttps
#RequestMapping(value = "/test", method = RequestMethod.POST)
public ResponseEntity<String> doAction(#NonNull #RequestBody CustomRequest[] requests) {
It looks like the 415 is happening inside spring mvc engine and it doesn't event reach your controller so that you can't really place the logs in our code (in doAction method for example).
Try to enable tomcat embedded access logs and you'll see the file with all the requests and return status. These are disabled by default so you should add the following into application.properties or yaml:
server.tomcat.accesslog.enabled=true
There are some configurations / customizations you can do with that, you can read about them in this tutorial for example

How can I test a secured endpoint with Awaitility in Spring boot?

I'm using spring boot and I want to assert an asynchronous side effect by calling a secured endpoint with MockMvc.
I have been using Awaitility, but apparently the mocked security context is lost when executing in a different thread.
I couldn't find a way of passing the context, I tried with SecurityContextHolder.setContext() but it didn't work, I guess spring's MockMvc stores the context in a different way.
#Test
#WithMockUser(authorities = "admin", username = "user")
void shouldRunSideEffectAsync() throws Exception {
mockMvc.perform(post("/foo")).andExpect(status().isAccepted());
await()
.atMost(TIMEOUT)
.untilAsserted(() -> mockMvc.perform(get("/foo")).andExpect(status().isOk()));
}
The GET would return 404 for a while and then 200 when the async task is completed. However this will always return 403 as the MockUser info is lost.
How can I solve this?
You almost got it. Security for MockMvc is implemented by TestSecurityContextHolderPostProcessor, which uses the TestSecurityContextHolder to set/get the security context. That is just a wrapper around the SecurityContextHolder.
So you can use TestSecurityContextHolder.setContext() in the awaitility thread and it should work.

How can I see the json coming from the client when using Spring-MVC?

A client software is trying to access my Spring-MVC rest server, but it's getting a 400 (Bad Request) response every time. I know my server is fine (it's in use by many other clients), but I cannot debug the client application, so I cannot see what it is sending.
Is there a way for me to see what JSON I am receiving before Spring tries to convert it to an entity and fails? It's okay if I can only do this at debug time, I just need to be able to give support to this application's creators.
Just in case, here is the spring-mvc controller method:
#Named
#RequestMapping(value = "/taskmanager/task")
public class TaskManagerTaskRest {
#RequestMapping(value = "", method = RequestMethod.POST)
#ResponseBody
public void createTask(#RequestBody Task task, HttpServletRequest request,
HttpServletResponse response) throws CalabacinException {
// This code never gets executed because the Task json is invalid, but I don't know how I could see it.
...
...
}
}
Try to use Fiddler. It will help you to catch HTTP requests/responses. You will be able to see your JSON.
You can create and use a AbstractRequestLoggingFilter filter implementation and conditionally log the relevant parts of the request. You should use ContentCachingRequestWrapper to wrap the request.

flex blazeds spring exception translator

I am using spring exception translator to wrap java exception into flex exception.
public void testException()throws Exception{
throw new Exception("my exception");
}
But for some reason, I am getting IllegalAccessError. The code sections are entering the testException and the Translator class.
Question:
Why it trying to get log target level? Can someone help me resolve this please.
Below is the lines from the log:
MyExceptionTranslatorImpl.translate()
class java.lang.IllegalAccessError
MyExceptionTranslatorImpl.translate()
java.lang.IllegalAccessError: tried to access method **flex.messaging.log.Log.getTargetLevel()S** from class flex.messaging.MessageException
MyExceptionTranslatorImpl.translate()
tried to access method
flex.messaging.log.Log.getTargetLevel()S from class flex.messaging.MessageException
[BlazeDS] tried to access method flex.messaging.log.Log.getTargetLevel()S from class flex.messaging.MessageException
[BlazeDS] Serializing AMF/HTTP response
This turned out to be mismatch in jars. Thank you Cornel Creanga for the initial response.
I also verified that throwing an java.lang.exception was enough to catch the error on the client side.

Resources