Auto-configured JSON Tests
To test that object JSON serialization and deserialization is working as expected, you can use the @JsonTest
annotation.
@JsonTest
auto-configures the available supported JSON mapper, which can be one of the following libraries:
-
Jackson
ObjectMapper
, any@JsonComponent
beans and any JacksonModule
s -
Gson
-
Jsonb
A list of the auto-configurations that are enabled by @JsonTest can be found in the appendix.
|
If you need to configure elements of the auto-configuration, you can use the @AutoConfigureJsonTesters
annotation.
Spring Boot includes AssertJ-based helpers that work with the JSONAssert and JsonPath libraries to check that JSON appears as expected.
The JacksonTester
, GsonTester
, JsonbTester
, and BasicJsonTester
classes can be used for Jackson, Gson, Jsonb, and Strings respectively.
Any helper fields on the test class can be @Autowired
when using @JsonTest
.
The following example shows a test class for Jackson:
-
Java
-
Kotlin
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.json.JsonTest;
import org.springframework.boot.test.json.JacksonTester;
import static org.assertj.core.api.Assertions.assertThat;
@JsonTest
class MyJsonTests {
@Autowired
private JacksonTester<VehicleDetails> json;
@Test
void serialize() throws Exception {
VehicleDetails details = new VehicleDetails("Honda", "Civic");
// Assert against a `.json` file in the same package as the test
assertThat(this.json.write(details)).isEqualToJson("expected.json");
// Or use JSON path based assertions
assertThat(this.json.write(details)).hasJsonPathStringValue("@.make");
assertThat(this.json.write(details)).extractingJsonPathStringValue("@.make").isEqualTo("Honda");
}
@Test
void deserialize() throws Exception {
String content = "{\"make\":\"Ford\",\"model\":\"Focus\"}";
assertThat(this.json.parse(content)).isEqualTo(new VehicleDetails("Ford", "Focus"));
assertThat(this.json.parseObject(content).getMake()).isEqualTo("Ford");
}
}
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.json.JsonTest
import org.springframework.boot.test.json.JacksonTester
@JsonTest
class MyJsonTests(@Autowired val json: JacksonTester<VehicleDetails>) {
@Test
fun serialize() {
val details = VehicleDetails("Honda", "Civic")
// Assert against a `.json` file in the same package as the test
assertThat(json.write(details)).isEqualToJson("expected.json")
// Or use JSON path based assertions
assertThat(json.write(details)).hasJsonPathStringValue("@.make")
assertThat(json.write(details)).extractingJsonPathStringValue("@.make").isEqualTo("Honda")
}
@Test
fun deserialize() {
val content = "{\"make\":\"Ford\",\"model\":\"Focus\"}"
assertThat(json.parse(content)).isEqualTo(VehicleDetails("Ford", "Focus"))
assertThat(json.parseObject(content).make).isEqualTo("Ford")
}
}
JSON helper classes can also be used directly in standard unit tests.
To do so, call the initFields method of the helper in your @Before method if you do not use @JsonTest .
|
If you use Spring Boot’s AssertJ-based helpers to assert on a number value at a given JSON path, you might not be able to use isEqualTo
depending on the type.
Instead, you can use AssertJ’s satisfies
to assert that the value matches the given condition.
For instance, the following example asserts that the actual number is a float value close to 0.15
within an offset of 0.01
.
-
Java
-
Kotlin
@Test
void someTest() throws Exception {
SomeObject value = new SomeObject(0.152f);
assertThat(this.json.write(value)).extractingJsonPathNumberValue("@.test.numberValue")
.satisfies((number) -> assertThat(number.floatValue()).isCloseTo(0.15f, within(0.01f)));
}
@Test
fun someTest() {
val value = SomeObject(0.152f)
assertThat(json.write(value)).extractingJsonPathNumberValue("@.test.numberValue")
.satisfies(ThrowingConsumer { number ->
assertThat(number.toFloat()).isCloseTo(0.15f, within(0.01f))
})
}