When using a @JsonTest
with an @Autowired
JacksonTester
, how can I test if a certain property is not present?
Suppose you have this object to serialize:
@JsonInclude(JsonInclude.Include.NON_NULL)
public class MyTestObject {
private Boolean myProperty;
// getter and setter
}
With this test:
@RunWith(SpringRunner.class)
@JsonTest
public class MyTestObjectTest {
@Autowired
private JacksonTester<MyTestObject> tester;
public void testPropertyNotPresent() {
JsonContent content = tester.write(new MyTestObject());
assertThat(content).???("myProperty");
}
}
Is there a method to put in the ???
so that it validates that the property is not in the resulting JSON when it is null
?
As a workaround, I currently use:
assertThat(content).doesNotHave(new Condition<>(
charSequence -> charSequence.toString().contains("myProperty"),
"The property 'myProperty' should not be present"));
But that is not exactly the same of course.
You can use the JSON path assertions to check values, however, you can't currently use it to check if the path itself is present. For example, if you use the following:
JsonContent<MyTestObject> content = this.tester.write(new MyTestObject());
assertThat(content).hasEmptyJsonPathValue("myProperty");
It will pass for both {"myProperty": null}
and {}
.
If you to test that a property is present but null
you'll need to write something like this:
private Consumer<String> emptyButPresent(String path) {
return (json) -> {
try {
Object value = JsonPath.compile(path).read(json);
assertThat(value).as("value for " + path).isNull();
} catch(PathNotFoundException ex) {
throw new AssertionError("Expected " + path + " to be present", ex);
}
};
}
You can then do the following:
assertThat(content.getJson()).satisfies(emptyButPresent("testProperty"));
Incidentally, your string assertion could also be simplified to:
assertThat(content.toString()).doesNotContain("myProperty");