Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring @JsonTest does not respect Jackson2ObjectMapperBuilderCustomizer customization bean

I have a @JsonTest test case which doesn't find a @Configuration class containing a Jackson2ObjectMapperBuilderCustomizer bean, and so the test fails. I can fix this with an @Import(...). Is there a way to make the @JsonTest find my configuration automatically, or is an @Import expected and the only way?

Context:

Using Spring Boot Starter Parent v. 2.5.3.

My application needs to use ISO-8601 basic formatting for timestamps, which I have configured via Jackson2ObjectMapperBuilderCustomizer as follows:

@Configuration
public class ObjectMapperConfig {
  @Bean
  public Jackson2ObjectMapperBuilderCustomizer jacksonCustomizer() {
    return builder -> {
      builder.dateFormat(new StdDateFormat().withColonInTimeZone(false));
    };
  }
}

I wrote a small test to confirm that the ObjectMapper formats dates the expected way. However, @JsonTest does not discover my @Configuration with the customizations, so the test fails unless I explicitly @Import(ObjectMapperConfig.class):

@JsonTest
@Import(ObjectMapperConfig.class) // This is required!
public class ObjectMapperConfigTest {

  @Autowired ObjectMapper mapper;

  @Test
  public void dateFormat() throws Exception {
    var input = Date.from(Instant.ofEpochMilli(0));

    var actual = mapper.writeValueAsString(input);

    // Write all dates in ISO-8601 Basic (not extended) format.
    // Timezones should be formatted +0000 instead of +00:00
    assertEquals("\"1970-01-01T00:00:00.000+0000\"", actual);
  }
}

My understanding of @JsonTest is that it only discovers @JsonComponent annotations, so it would ignore normal @Configuration, which means (for me) it doesn't actually test the Json serialization layer. This answer suggests what I am doing should work, but that does not seem to be the case. Is using an @Import correct, or should I annotate my configuration otherwise? Based on the documentation, it seems inappropriate to use @JsonComponent instead of @Configuration, and the @JsonTest documentation doesn't seem to comment on my scenario. Advice is appreciated. Thanks!

like image 246
Tomboyo Avatar asked Sep 11 '25 01:09

Tomboyo


1 Answers

The below approach works for me as of Spring Boot 2.5.12:

import com.fasterxml.jackson.annotation.JsonInclude;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.jackson.JsonComponent;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

/**
 * This customizer is annotated with @JsonComponent and hence is used both for production and @JsonTest tests.
 * More details <a href="https://stackoverflow.com/questions/68730482/spring-jsontest-does-not-respect-jackson2objectmapperbuildercustomizer-customiz">here</a>
 */
@JsonComponent
public class JacksonCustomizer implements Jackson2ObjectMapperBuilderCustomizer {
    @Override
    public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
        jacksonObjectMapperBuilder.serializationInclusion(JsonInclude.Include.NON_NULL);
    }
}

As much as I personally prefer to use @Configuration + @Bean, I had to refrain to @JsonComponent here because @Import seems to be more error-prone in the long run.

like image 85
wheleph Avatar answered Sep 12 '25 14:09

wheleph