DEV Community

Discussion on: Json conversion errors with Spring MockMvc

Collapse
 
laptevn profile image
Nickolay Laptev

Are you sure we can "unit test" a controller?

Another point.
On a controller or endpoint layer we operate with requests and responses. Hence we have a response body in our testing scenario that is a plain text. Text is transferred via network, not information about data type.
So any manipulations with data type of response body on tests side looks strange for me.

Collapse
 
piczmar_0 profile image
Marcin Piczkowski

"Are you sure we can "unit test" a controller" - yes, you can.

"..any manipulations with data type of response body on tests side looks strange for me." - kind of true, but the thing is that because you are using MockMvc and not really the runtime config you get different JSON parser by default anyway. You can get as close as possible to your runtime config through additional hacks which I described in the post. This is a question not whether you can unit test controllers but whether you should. Integration tests have its own pros & cons.

Collapse
 
laptevn profile image
Nickolay Laptev • Edited

1 Within unit tests we operate only with methods of a class. Within components tests we can operate with several classes.
But we don't know anything about controllers, endpoints, threads, timers, file system in unit (and component) tests.
We know about them in integration tests.

Remember last year where we had to fight with crazy "unit tests" that run for ages :-) Lack of separation between tests was the major issue I saw in all products.
Pure unit and component tests run super fast since they operate only with RAM.

2 Let's identify what we want to test ignoring how we name this test (i.e. integration or unit test).
If we test an endpoint (web service according to target post), probably we want to verify how this endpoint reacts to incoming requests by checking what is returned as a response.
Since response body is plain text in our case this is what we want to check.
But we convert this body to some format by adding some workarounds to achieve that and just to finally verify the body itself. Why not to verify the body as is without redundant conversion to some format? :-)
So we could replace
.andExpect(jsonPath("$.value", is(ExampleController.VALUE_DOUBLE_FAIL)));
with
.andExpect(jsonPath("$.value",
is(ExampleController.VALUE_BIG_DECIMAL_FAIL.toString())));

and remove a workaround with JSON parser. Please note that this is a pseudo code (i.e. comparing string values) but the idea should be clear.
In this case we don't loose anything since we verify the only thing we care - response body.

Thread Thread
 
piczmar_0 profile image
Marcin Piczkowski • Edited
  1. I'm talking about unit tests as such that do not require whole spring context to start.

  2. That won't work because of the library limitation. I see your point but that's how the asserts works. If you try to compare "to-string" expected value with the decimal value from controller they will fail. The library would need to convert the decimals somewhow to string before the assert and this would also be a smelly hack :) In current state you'll get:

java.lang.AssertionError: JSON path "$.value"
Expected: is "0.071854545056424"
     but: was <0.071854545056424>
Expected :is "0.071854545056424"

Actual   :<0.071854545056424>