I hate to find bugs in my automated tests code. It is a test. It is supposed to find bugs, not to hide them, right?
I use jackson for serialization/deserialization in my tests code. I use it since I started writing in Java. All projects I’ve been involved to were using jackson. I thought that I know what is it and how to use it. OK, lets go straight to the point.
Recently I saw field type mismatch in a test log, but test was positive. Jackson hasn’t thrown any exception. After some digging into jackson docs I found that jackson has type coercion which is enabled by default.
My test is could be described like this: make POST http request and verify response body. Json could be simplified to this:
{
"id": 666444888,
"name": "John Doe"
}
but the problem is that I expected id to be a String. I thought, that jackson will throw an exception with following DTO:
public class Person {
public String id;
public String name;
}
This DTO will work with both String id and Integer id. System under test is a service with public API. It can’t change contract types, clients application could break, because not everyone use jackson or other libraries don’t have such kind a type coercions.
I thought that Java strict type system and jackson will protect me from this kind of errors. But it haven’t 🙂 So, how to fix it? Luckily for me, this behavior can be changed. With following ObjectMapper configuration jackson will throw an InvalidFormatException:
var mapper = JsonMapper.builder()
.withCoercionConfig(LogicalType.Textual,cfg -> cfg.setCoercion(CoercionInputShape.Integer, CoercionAction.Fail))
.build()
// next line will throw an exception if id field in json is an Integer
Person person = mapper.readValue(jsonBody, Person.class)
Be careful with libraries, folks. There could be hidden features like this which you don’t want to use.