
Unit Test Json Serialization
- 1.7k installs
- 311 repo stars
- Updated June 22, 2026
- giuseppe-trisciuoglio/developer-kit
Patterns and practices for unit testing JSON serialization/deserialization with Spring @JsonTest and Jackson, including POJO mapping, custom serializers, field annotations, and polymorphic types.
About
This skill provides patterns for unit testing JSON serialization/deserialization using Spring's @JsonTest annotation and Jackson library. Developers use it when validating DTOs, custom serializers, field mappings (@JsonProperty, @JsonIgnore), date/time formats, and polymorphic types. Key workflows include annotating test classes with @JsonTest, autowiring JacksonTester for type-safe assertions, testing both serialization (write) and deserialization (parse), validating round-trip conversions, and handling edge cases like nulls, missing fields, and nested objects. The skill covers setup with Maven/Gradle, basic POJO mapping, nested objects, custom Jackson serializers, and polymorphic type deserialization with @JsonTypeInfo.
- Annotate test class with @JsonTest to enable JacksonTester auto-configuration for Spring Boot
- Use extractingJsonPath* methods to assert individual JSON fields rather than full string comparisons
- Test both serialization (write) and deserialization (parse) for complete JSON mapping coverage
- Handle edge cases: null fields, @JsonInclude behavior, @JsonIgnore, missing fields, and nested structures
- Validate polymorphic types with @JsonTypeInfo and @JsonSubTypes for correct runtime deserialization
Unit Test Json Serialization by the numbers
- 1,657 all-time installs (skills.sh)
- +57 installs in the week ending Jul 28, 2026 (Skillselion tracking)
- Ranked #436 of 2,184 Testing & QA skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Jul 28, 2026 (Skillselion catalog sync)
unit-test-json-serialization capabilities & compatibility
- Capabilities
- serialize java objects to json with jacksonteste · deserialize json strings to java objects · assert json field paths with extractingjsonpath* · test custom jackson serializers and deserializer · validate polymorphic type deserialization
- Works with
- github
- Use cases
- testing · code review · debugging
- Platforms
- macOS · Windows · Linux · WSL
- Runs
- Runs locally
npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill unit-test-json-serializationAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1.7k |
|---|---|
| repo stars | ★ 311 |
| Security audit | 3 / 3 scanners passed |
| Last updated | June 22, 2026 |
| Repository | giuseppe-trisciuoglio/developer-kit ↗ |
What it does
Write unit tests for JSON serialization and deserialization in Spring Boot applications using @JsonTest and Jackson.
Who is it for?
Testing DTOs and data transfer objects, validating Jackson custom serializers, ensuring @JsonProperty and @JsonIgnore annotations work correctly, testing date/time format handling.
Skip if: Full integration testing of REST endpoints (use @WebMvcTest or @SpringBootTest), testing non-Jackson JSON libraries, testing UI serialization.
When should I use this skill?
Writing unit tests for Spring Boot REST APIs, validating custom Jackson serializers, testing DTO field mappings, ensuring JSON round-trip conversion works.
What you get
Write comprehensive unit tests that verify JSON field mappings, custom serializers, date formats, null handling, and polymorphic type deserialization.
- Unit test class annotated with @JsonTest
- JacksonTester type-safe assertions
- Test cases for serialization, deserialization, edge cases, and round-trip conversion
By the numbers
- Covers 6 core testing patterns: basic POJO, custom properties, nested objects, date/time, custom serializers, polymorphi
- Provides debugging workflow table with 7 common failure symptoms and resolutions
- Includes 8 runnable code examples with Maven/Gradle setup
Files
Unit Testing JSON Serialization with @JsonTest
Overview
Provides patterns for unit testing JSON serialization and deserialization using Spring's @JsonTest and Jackson. Covers POJO mapping, custom serializers, field name mappings, nested objects, date/time formatting, and polymorphic types.
When to Use
- Testing JSON serialization/deserialization of DTOs
- Verifying custom Jackson serializers/deserializers
- Validating
@JsonProperty,@JsonIgnore, and field name mappings - Testing date/time format handling (LocalDateTime, Date)
- Testing null handling and missing fields
- Testing polymorphic type deserialization
Instructions
1. Annotate test class with `@JsonTest` → Enables JacksonTester auto-configuration 2. Autowire JacksonTester for target type → Provides type-safe JSON assertions 3. Test serialization → Call json.write(object) and assert JSON paths with extractingJsonPath* 4. Test deserialization → Call json.parse(json) or json.parseObject(json) and assert object state 5. Validate round-trip → Serialize, then deserialize, verify same data (if object is properly comparable) 6. Test edge cases → Null values, missing fields, empty collections, invalid JSON 7. Add validation checkpoints: After each assertion, verify the test fails meaningfully with wrong data
Examples
Maven Setup
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>Gradle Setup
dependencies {
implementation("org.springframework.boot:spring-boot-starter-json")
testImplementation("org.springframework.boot:spring-boot-starter-test")
}Basic Serialization and Deserialization
@JsonTest
class UserDtoJsonTest {
@Autowired
private JacksonTester<UserDto> json;
@Test
void shouldSerializeUserToJson() throws Exception {
UserDto user = new UserDto(1L, "Alice", "alice@example.com", 25);
JsonContent<UserDto> result = json.write(user);
result
.extractingJsonPathNumberValue("$.id").isEqualTo(1)
.extractingJsonPathStringValue("$.name").isEqualTo("Alice")
.extractingJsonPathStringValue("$.email").isEqualTo("alice@example.com")
.extractingJsonPathNumberValue("$.age").isEqualTo(25);
}
@Test
void shouldDeserializeJsonToUser() throws Exception {
String json_content = "{\"id\":1,\"name\":\"Alice\",\"email\":\"alice@example.com\",\"age\":25}";
UserDto user = json.parse(json_content).getObject();
assertThat(user.getId()).isEqualTo(1L);
assertThat(user.getName()).isEqualTo("Alice");
assertThat(user.getEmail()).isEqualTo("alice@example.com");
assertThat(user.getAge()).isEqualTo(25);
}
@Test
void shouldHandleNullFields() throws Exception {
String json_content = "{\"id\":1,\"name\":null,\"email\":\"alice@example.com\"}";
UserDto user = json.parse(json_content).getObject();
assertThat(user.getName()).isNull();
}
}Custom JSON Properties
public class Order {
@JsonProperty("order_id")
private Long id;
@JsonProperty("total_amount")
private BigDecimal amount;
@JsonIgnore
private String internalNote;
}
@JsonTest
class OrderJsonTest {
@Autowired
private JacksonTester<Order> json;
@Test
void shouldMapJsonPropertyNames() throws Exception {
String json_content = "{\"order_id\":123,\"total_amount\":99.99}";
Order order = json.parse(json_content).getObject();
assertThat(order.getId()).isEqualTo(123L);
assertThat(order.getAmount()).isEqualByComparingTo(new BigDecimal("99.99"));
}
@Test
void shouldIgnoreJsonIgnoreFields() throws Exception {
Order order = new Order(123L, new BigDecimal("99.99"));
order.setInternalNote("Secret");
assertThat(json.write(order).json).doesNotContain("internalNote");
}
}Nested Objects
public class Product {
private Long id;
private String name;
private Category category;
private List<Review> reviews;
}
@JsonTest
class ProductJsonTest {
@Autowired
private JacksonTester<Product> json;
@Test
void shouldSerializeNestedObjects() throws Exception {
Product product = new Product(1L, "Laptop", new Category(1L, "Electronics"));
JsonContent<Product> result = json.write(product);
result
.extractingJsonPathNumberValue("$.category.id").isEqualTo(1)
.extractingJsonPathStringValue("$.category.name").isEqualTo("Electronics");
}
@Test
void shouldDeserializeNestedObjects() throws Exception {
String json_content = "{\"id\":1,\"name\":\"Laptop\",\"category\":{\"id\":1,\"name\":\"Electronics\"}}";
Product product = json.parse(json_content).getObject();
assertThat(product.getCategory().getName()).isEqualTo("Electronics");
}
@Test
void shouldHandleListOfNestedObjects() throws Exception {
String json_content = "{\"id\":1,\"reviews\":[{\"rating\":5},{\"rating\":4}]}";
Product product = json.parse(json_content).getObject();
assertThat(product.getReviews()).hasSize(2);
}
}Date/Time Formatting
@JsonTest
class DateTimeJsonTest {
@Autowired
private JacksonTester<Event> json;
@Test
void shouldFormatDateTimeCorrectly() throws Exception {
LocalDateTime dt = LocalDateTime.of(2024, 1, 15, 10, 30, 0);
json.write(new Event("Conference", dt))
.extractingJsonPathStringValue("$.scheduledAt").isEqualTo("2024-01-15T10:30:00");
}
}Custom Serializers
public class CustomMoneySerializer extends JsonSerializer<BigDecimal> {
@Override
public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeString(value == null ? null : String.format("$%.2f", value));
}
}
@JsonTest
class CustomSerializerTest {
@Autowired
private JacksonTester<Price> json;
@Test
void shouldUseCustomSerializer() throws Exception {
json.write(new Price(new BigDecimal("99.99")))
.extractingJsonPathStringValue("$.amount").isEqualTo("$99.99");
}
}Polymorphic Deserialization
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = CreditCard.class, name = "credit_card"),
@JsonSubTypes.Type(value = PayPal.class, name = "paypal")
})
public abstract class PaymentMethod { }
@JsonTest
class PolymorphicJsonTest {
@Autowired
private JacksonTester<PaymentMethod> json;
@Test
void shouldDeserializeCreditCard() throws Exception {
String json_content = "{\"type\":\"credit_card\",\"id\":\"card123\"}";
assertThat(json.parse(json_content).getObject()).isInstanceOf(CreditCard.class);
}
@Test
void shouldDeserializePayPal() throws Exception {
String json_content = "{\"type\":\"paypal\",\"id\":\"pp123\"}";
assertThat(json.parse(json_content).getObject()).isInstanceOf(PayPal.class);
}
}Best Practices
- Test serialization AND deserialization for complete coverage
- Verify JSON paths individually rather than comparing full JSON strings
- Test null handling explicitly — null fields may be included or excluded depending on
@JsonInclude - Use
extractingJsonPath*methods for precise field assertions - Test round-trip: serialize an object, deserialize the JSON, verify the result matches
- Validate edge cases: empty strings, empty collections, deeply nested structures
- Group related assertions in a single test for clarity
Constraints and Warnings
- `@JsonTest` loads limited context: Only JSON-related beans; use
@SpringBootTestfor full Spring context - Jackson version: Ensure annotation versions match the Jackson version in use
- Date formats: ISO-8601 is default; use
@JsonFormatfor custom patterns - Null handling: Use
@JsonInclude(Include.NON_NULL)to exclude nulls from serialization - Circular references: Use
@JsonManagedReference/@JsonBackReferenceto prevent infinite loops - Immutable objects: Use
@JsonCreator+@JsonPropertyfor constructor-based deserialization - Polymorphic types:
@JsonTypeInfomust correctly identify the subtype for deserialization to work
Debugging Workflow
When a JSON test fails, follow this workflow:
| Failure Symptom | Common Cause | How to Verify |
|---|---|---|
JsonPath assertion fails | Field name mismatch | Check @JsonProperty spelling matches JSON key |
| Null expected but got value | @JsonInclude(NON_NULL) configured | Verify annotation on field/class |
| Deserialization returns wrong type | Missing @JsonTypeInfo | Add type info property to JSON or configure subtype mapping |
| Date format mismatch | Format string incorrect | Confirm @JsonFormat(pattern=...) matches expected string |
| Missing field in output | @JsonIgnore or transient modifier | Check field for @JsonIgnore or transient keyword |
| Nested object is null | Inner JSON missing or malformed | Log parsed JSON; verify inner structure matches POJO |
JsonParseException | Malformed JSON string | Validate JSON syntax; check for unescaped characters |
Validation checkpoint after fixing: Re-run the test — if it passes, write a complementary test for the opposite case (e.g., if you fixed null handling, add a test for non-null values to prevent regression).
References
Related skills
Forks & variants (1)
Unit Test Json Serialization has 1 known copy in the catalog totaling 21 installs. They canonicalize to this original listing.
- giuseppe-trisciuoglio - 21 installs
How it compares
Use unit-test-json-serialization for fast Jackson mapping tests; use integration test skills when full HTTP endpoints and databases must be exercised together.
FAQ
What is the difference between json.write() and json.parse()?
json.write(object) serializes a Java object to JSON and returns JsonContent for assertions; json.parse(jsonString) deserializes JSON to a Java object.
Why should I test both serialization and deserialization?
Serialization ensures objects convert to correct JSON structure; deserialization ensures JSON converts back to correct object state. Testing both prevents round-trip data loss.
How do I handle null fields in JSON tests?
Use @JsonInclude(Include.NON_NULL) to exclude nulls from serialization, then test that null fields are either omitted or included as expected.
Is Unit Test Json Serialization safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.