Starter for testing Spring Boot applications with libraries including JUnit Jupiter, Hamcrest and Mockito
—
Specialized JSON testing utilities with marshalling support for Jackson, Gson, and JSON-B, providing comprehensive JSON serialization testing capabilities.
JSON testing utilities for Jackson serialization and deserialization.
/**
* AssertJ assertions for testing JSON serialization/deserialization using Jackson
* @since 1.4.0
*/
public class JacksonTester<T> extends AbstractJsonMarshalTester<T> {
/**
* Create a JacksonTester for the given type
*/
public static <T> JacksonTester<T> forType(Class<T> type);
/**
* Write the given object as JSON
*/
public JsonContent<T> write(T object) throws IOException;
/**
* Parse the given JSON into an object
*/
public T parseObject(String json) throws IOException;
/**
* Parse the given JSON from a Resource into an object
*/
public T read(Resource resource) throws IOException;
/**
* Parse the given JSON from an InputStream into an object
*/
public T read(InputStream inputStream) throws IOException;
}
/**
* Base class for JSON marshalling testers
*/
public abstract class AbstractJsonMarshalTester<T> {
/**
* Get the object mapper being used
*/
protected abstract Object getObjectMapper();
/**
* Initialize this tester for the given class and object mapper
*/
public void initFields(Object testInstance, ObjectMapper objectMapper);
}Usage Examples:
@JsonTest
class JacksonJsonTest {
@Autowired
private JacksonTester<User> json;
@Test
void serializeUser() throws Exception {
User user = new User("test@example.com", "Test User", 25);
JsonContent<User> result = json.write(user);
assertThat(result)
.hasJsonPathStringValue("@.email", "test@example.com")
.hasJsonPathStringValue("@.name", "Test User")
.hasJsonPathNumberValue("@.age", 25);
}
@Test
void deserializeUser() throws Exception {
String content = "{\"email\":\"test@example.com\",\"name\":\"Test User\",\"age\":25}";
User user = json.parseObject(content);
assertThat(user.getEmail()).isEqualTo("test@example.com");
assertThat(user.getName()).isEqualTo("Test User");
assertThat(user.getAge()).isEqualTo(25);
}
@Test
void deserializeFromResource() throws Exception {
ClassPathResource resource = new ClassPathResource("user.json");
User user = json.read(resource);
assertThat(user).isNotNull();
assertThat(user.getEmail()).isNotBlank();
}
}JSON testing utilities for Gson serialization and deserialization.
/**
* AssertJ assertions for testing JSON serialization/deserialization using Gson
* @since 1.4.0
*/
public class GsonTester<T> extends AbstractJsonMarshalTester<T> {
/**
* Create a GsonTester for the given type
*/
public static <T> GsonTester<T> forType(Class<T> type);
/**
* Write the given object as JSON using Gson
*/
public JsonContent<T> write(T object) throws IOException;
/**
* Parse the given JSON into an object using Gson
*/
public T parseObject(String json) throws IOException;
/**
* Parse the given JSON from a Resource into an object using Gson
*/
public T read(Resource resource) throws IOException;
}JSON testing utilities for JSON-B serialization and deserialization.
/**
* AssertJ assertions for testing JSON serialization/deserialization using JSON-B
* @since 2.0.0
*/
public class JsonbTester<T> extends AbstractJsonMarshalTester<T> {
/**
* Create a JsonbTester for the given type
*/
public static <T> JsonbTester<T> forType(Class<T> type);
/**
* Write the given object as JSON using JSON-B
*/
public JsonContent<T> write(T object) throws IOException;
/**
* Parse the given JSON into an object using JSON-B
*/
public T parseObject(String json) throws IOException;
/**
* Parse the given JSON from a Resource into an object using JSON-B
*/
public T read(Resource resource) throws IOException;
}JSON testing utilities without marshalling for simple JSON testing.
/**
* Basic JSON testing utilities without object marshalling
* @since 1.4.0
*/
public class BasicJsonTester {
/**
* Create JSON content from the given object
*/
public JsonContent<Object> from(CharSequence json);
/**
* Create JSON content from the given Resource
*/
public JsonContent<Object> from(Resource resource) throws IOException;
/**
* Create JSON content from the given InputStream
*/
public JsonContent<Object> from(InputStream inputStream) throws IOException;
}Usage Examples:
@JsonTest
class BasicJsonTest {
@Autowired
private BasicJsonTester json;
@Test
void testJsonStructure() throws Exception {
String jsonString = "{\"users\":[{\"name\":\"Alice\",\"age\":30},{\"name\":\"Bob\",\"age\":25}]}";
JsonContent<Object> content = json.from(jsonString);
assertThat(content)
.hasJsonPathArrayValue("@.users")
.hasJsonPathValue("@.users[0].name", "Alice")
.hasJsonPathValue("@.users[1].age", 25);
}
}AssertJ-based assertions for JSON content validation.
/**
* AssertJ assertions for JSON content
* @since 1.4.0
*/
public class JsonContentAssert extends AbstractAssert<JsonContentAssert, CharSequence> {
/**
* Verify that the JSON is equal to the given expected JSON
*/
public JsonContentAssert isEqualToJson(CharSequence expected);
/**
* Verify that the JSON is equal to the JSON in the given Resource
*/
public JsonContentAssert isEqualToJson(Resource expected);
/**
* Verify that the JSON contains the given JSONPath expression
*/
public JsonContentAssert hasJsonPathValue(CharSequence expression);
/**
* Verify that the JSON has a string value at the given JSONPath
*/
public JsonContentAssert hasJsonPathStringValue(CharSequence expression);
/**
* Verify that the JSON has a string value at the given JSONPath with expected value
*/
public JsonContentAssert hasJsonPathStringValue(CharSequence expression, String expectedValue);
/**
* Verify that the JSON has a number value at the given JSONPath
*/
public JsonContentAssert hasJsonPathNumberValue(CharSequence expression);
/**
* Verify that the JSON has a number value at the given JSONPath with expected value
*/
public JsonContentAssert hasJsonPathNumberValue(CharSequence expression, Number expectedValue);
/**
* Verify that the JSON has a boolean value at the given JSONPath
*/
public JsonContentAssert hasJsonPathBooleanValue(CharSequence expression);
/**
* Verify that the JSON has a boolean value at the given JSONPath with expected value
*/
public JsonContentAssert hasJsonPathBooleanValue(CharSequence expression, Boolean expectedValue);
/**
* Verify that the JSON has an array value at the given JSONPath
*/
public JsonContentAssert hasJsonPathArrayValue(CharSequence expression);
/**
* Verify that the JSON has a map value at the given JSONPath
*/
public JsonContentAssert hasJsonPathMapValue(CharSequence expression);
/**
* Extract the value at the given JSONPath for further assertions
*/
public JsonContentAssert extractingJsonPathValue(String expression);
/**
* Extract the string value at the given JSONPath for further assertions
*/
public JsonContentAssert extractingJsonPathStringValue(String expression);
/**
* Extract the number value at the given JSONPath for further assertions
*/
public JsonContentAssert extractingJsonPathNumberValue(String expression);
/**
* Verify that the JSON does not have a value at the given JSONPath
*/
public JsonContentAssert doesNotHaveJsonPathValue(CharSequence expression);
/**
* Verify that the JSON is not equal to the given expected JSON
*/
public JsonContentAssert isNotEqualToJson(CharSequence expected);
/**
* Verify that the JSON is strict equal to the given expected JSON
*/
public JsonContentAssert isStrictlyEqualToJson(CharSequence expected);
}
/**
* Wrapper around JSON content for testing
* @since 1.4.0
*/
public final class JsonContent<T> implements CharSequence {
/**
* Get the actual JSON content as a String
*/
@Override
public String toString();
/**
* Get the JSON content as bytes
*/
public byte[] getBytes();
/**
* Get the original object that was serialized (if available)
*/
public T getObject();
/**
* Create AssertJ assertions for this JSON content
*/
public JsonContentAssert assertThat();
/**
* Get JSON content length
*/
@Override
public int length();
/**
* Get character at the specified index
*/
@Override
public char charAt(int index);
/**
* Get subsequence of the JSON content
*/
@Override
public CharSequence subSequence(int start, int end);
}AssertJ-based assertions for deserialized object content validation.
/**
* AssertJ assertions for object content from JSON deserialization
* @since 1.4.0
*/
public class ObjectContentAssert<A> extends AbstractAssert<ObjectContentAssert<A>, A> {
/**
* Verify that the object is equal to the expected object
*/
public ObjectContentAssert<A> isEqualTo(Object expected);
/**
* Verify that the object has the given field value
*/
public ObjectContentAssert<A> hasFieldOrPropertyWithValue(String name, Object value);
/**
* Verify that the object satisfies the given condition
*/
public ObjectContentAssert<A> satisfies(Consumer<A> requirements);
}
/**
* Wrapper around deserialized object content for testing
* @since 1.4.0
*/
public final class ObjectContent<T> {
/**
* Get the deserialized object
*/
public T getObject();
/**
* Create AssertJ assertions for this object content
*/
public ObjectContentAssert<T> assertThat();
/**
* Get string representation of the object
*/
@Override
public String toString();
}Auto-configuration for JSON testing components.
/**
* Auto-configuration for JSON testers
* @since 1.4.0
*/
@AutoConfiguration
@ConditionalOnClass({JsonTest.class, AssertJ.class})
public class JsonTestersAutoConfiguration {
/**
* Configure JacksonTester beans
*/
@Configuration
@ConditionalOnClass(ObjectMapper.class)
static class JacksonTesterConfiguration {
@Bean
public JacksonTester<?> jacksonTester();
}
/**
* Configure GsonTester beans
*/
@Configuration
@ConditionalOnClass(Gson.class)
static class GsonTesterConfiguration {
@Bean
public GsonTester<?> gsonTester();
}
/**
* Configure JsonbTester beans
*/
@Configuration
@ConditionalOnClass(Jsonb.class)
static class JsonbTesterConfiguration {
@Bean
public JsonbTester<?> jsonbTester();
}
}Advanced patterns for complex JSON testing scenarios.
Usage Examples:
@JsonTest
class AdvancedJsonTest {
@Autowired
private JacksonTester<UserList> userListJson;
@Autowired
private JacksonTester<User> userJson;
@Test
void testNestedJsonStructure() throws Exception {
User user1 = new User("alice@example.com", "Alice", 30);
User user2 = new User("bob@example.com", "Bob", 25);
UserList userList = new UserList(Arrays.asList(user1, user2));
JsonContent<UserList> result = userListJson.write(userList);
assertThat(result)
.hasJsonPathArrayValue("@.users")
.hasJsonPathStringValue("@.users[0].email", "alice@example.com")
.hasJsonPathStringValue("@.users[0].name", "Alice")
.hasJsonPathNumberValue("@.users[0].age", 30)
.hasJsonPathStringValue("@.users[1].email", "bob@example.com")
.hasJsonPathStringValue("@.users[1].name", "Bob")
.hasJsonPathNumberValue("@.users[1].age", 25);
}
@Test
void testJsonWithNullValues() throws Exception {
User user = new User("test@example.com", null, null);
JsonContent<User> result = userJson.write(user);
assertThat(result)
.hasJsonPathStringValue("@.email", "test@example.com")
.doesNotHaveJsonPathValue("@.name")
.doesNotHaveJsonPathValue("@.age");
}
@Test
void testJsonEquality() throws Exception {
String expected = """
{
"email": "test@example.com",
"name": "Test User",
"age": 25
}
""";
User user = new User("test@example.com", "Test User", 25);
JsonContent<User> result = userJson.write(user);
assertThat(result).isEqualToJson(expected);
}
@Test
void testJsonFromResource() throws Exception {
ClassPathResource expectedJson = new ClassPathResource("user-expected.json");
User user = new User("test@example.com", "Test User", 25);
JsonContent<User> result = userJson.write(user);
assertThat(result).isEqualToJson(expectedJson);
}
@Test
void testComplexJsonPath() throws Exception {
String complexJson = """
{
"users": [
{
"profile": {"name": "Alice", "preferences": {"theme": "dark"}},
"contacts": [{"type": "email", "value": "alice@example.com"}]
}
]
}
""";
JsonContent<Object> content = basicJson.from(complexJson);
assertThat(content)
.hasJsonPathStringValue("@.users[0].profile.name", "Alice")
.hasJsonPathStringValue("@.users[0].profile.preferences.theme", "dark")
.hasJsonPathStringValue("@.users[0].contacts[0].type", "email")
.hasJsonPathStringValue("@.users[0].contacts[0].value", "alice@example.com");
}
}
// Custom JSON configuration for testing
@TestConfiguration
static class JsonTestConfig {
@Bean
@Primary
public ObjectMapper testObjectMapper() {
return JsonMapper.builder()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.build();
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-springframework-boot--spring-boot-starter-test