Не отключается автоконфигурация ObjectMapper'а в тестах

Не отключается автоконфигурация ObjectMapper'а в тестах

Пытаюсь написать тесты для REST API с использованием кастомного (и в тестах, и в основной логике) ObjectMapper'а с включенной настройкой ACCEPT_SINGLE_VALUE_AS_ARRAY. В основной логике все работает, а в тестах - нет. Насколько я понял, где-то включается автоконфигурация, хотя я ее вроде отключаю по крайней мере в аннотации @SpringBootTest и @TestPropertySource.

Тестовый класс:

@SpringBootTest(classes = {TaskManagerApplication.class, MvcConfig.class}, properties = {"spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration"
+ ",spring.main.allow-bean-definition-overriding=true"
+ ",spring.jackson.deserialization.ACCEPT_SINGLE_VALUE_AS_ARRAY=true"
+ ",org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration"})
@TestPropertySource(properties = {"spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration"
        , "spring.main.allow-bean-definition-overriding=true"
        , "spring.jackson.deserialization.ACCEPT_SINGLE_VALUE_AS_ARRAY=true"
        , "org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration"})
public class TaskManagerIntegrationTests {
    
            @Autowired
            private MappingJackson2HttpMessageConverter jackson2HttpMessageConverter;
    
        @Autowired
        @Qualifier("myObjectMapper")
        private ObjectMapper objectMapper;

        @Autowired
        private PersonDetailsService personDetailsService;

        @Autowired
        private TaskService taskService;
        
        @Autowired
        private TaskRestController taskRestController;

        @Autowired
        private WebApplicationContext webApplicationContext;
        
        private MockMvc mockMvc;
        
        private List<Task> controlTasks;
        
        @BeforeEach
        public void setUp() {
            this.mockMvc = MockMvcBuilders.standaloneSetup(new TaskRestController())
            .setMessageConverters(this.jackson2HttpMessageConverter)
            .build();
            objectMapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
            fillTasksList();
        }
    
    @BeforeEach
    public void fillTasksList() {
        controlTasks = new ArrayList<>();
        Person person = personDetailsService.findById(3L);
        
        Task task1 = new Task();
        task1.setTitle("IntegrationTestTask-1");
        task1.setDescription("Task №1 for integration tests description");
        task1.setPriority(Task.Priority.LOW);
        task1.setStatus(Task.Status.AWAITING);
        task1.setAuthor(person);
        task1.setExecutor(person);
        task1 = taskService.save(task1);
        controlTasks.add(task1);
        
        Task task2 = new Task();
        task2.setTitle("Random Title");
        task2.setDescription("Random Description");
        task2.setAuthor(person);
        task2.setExecutor(person);
        task2.setPriority(Task.Priority.MEDIUM);
        task2.setStatus(Task.Status.PROCESSING);
        task2 = taskService.save(task2);
        controlTasks.add(task2);
    }
    
    
    @AfterEach
    public void clean() {
        taskService.deleteById(controlTasks.get(0).getId());
        taskService.deleteById(controlTasks.get(1).getId());
    }
    
    @Test
    public void correctRequestOfSingleExistingTaskMustSucces() throws JsonProcessingException, Exception {
          // здесь выводится true
          System.out.println("ACCEPT_SINGLE_VALUE_AS_ARRAY is enabled: " + objectMapper.isEnabled(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)); 
          Map<String, String> request = new HashMap<>();
          long id = controlTasks.get(0).getId();
          request.put("id", String.valueOf(id));
          
          mockMvc.perform(MockMvcRequestBuilders.get("/rest/tasks")
                    .contentType(MediaType.APPLICATION_JSON_VALUE).accept(MediaType.APPLICATION_JSON_VALUE)
                    .content(objectMapper.writeValueAsString(request)))
                    .andDo(print())
                    .andExpect(status().isOk())
                    .andExpect(jsonPath("$[0].id", Matchers.equalTo(id)));
    }
}

При этом в первой строчке теста выводится true, то есть строка:

ACCEPT_SINGLE_VALUE_AS_ARRAY is enabled: true

Но по факту эта настройка не используется. Пробовал некоторые варианты решения проблемы, все не перечислю.

Конфигурация:

@Configuration
public class MvcConfig implements WebMvcConfigurer {
    
    
   @Override
   public void addViewControllers(ViewControllerRegistry registry) {
      registry.addViewController("/").setViewName("index");
      registry.addViewController("").setViewName("index");
   }
   
   @Override
   public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
       converters.add(jackson2HttpMessageConverter());
   }
 
   @Bean
   public MappingJackson2HttpMessageConverter jackson2HttpMessageConverter() {
       MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
       converter.setObjectMapper(myObjectMapper());
       return converter;
   }
   
   
   @Bean
   HiddenHttpMethodFilter hiddenHttpMethodFilter() {
       return new HiddenHttpMethodFilter();
   }
   
   @Bean
   public HandlerMappingIntrospector mvcHandlerMappingIntrospector() {
       return new HandlerMappingIntrospector();
   }
    
   @Bean("myObjectMapper")
   //@Primary
   public ObjectMapper myObjectMapper() {
       final ObjectMapper objectMapper =  JsonMapper.builder()
           .addModule(new JavaTimeModule())
           .addModule(new Hibernate6Module())
           .addModule(new SimpleModule())
           .enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
           .configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true)
           .configure(SerializationFeature.INDENT_OUTPUT, true)
           .build(); 
       return objectMapper;
   }
   
   @Bean
   public Module datatypeHibernateModule() {
     return new Hibernate6Module();
   }
}

application-test.properties (практически идентично с application.properties):

spring.application.name=TaskManager

spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/effective_mobile_test
spring.datasource.username=postgres
spring.datasource.password=postgres

jakarta.persistence.jdbc.url=jdbc:postgresql://localhost:5432/effective_mobile_test

spring.jackson.deserialization.ACCEPT_SINGLE_VALUE_AS_ARRAY=true
spring.jackson.serialization.fail-on-empty-beans=false

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration

server.port=8080

spring.jpa.show-sql=true

spring.jpa.generate-ddl=false
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
spring.thymeleaf.extras.springsecurity5.enabled=true
spring.mvc.hiddenmethod.filter.enabled=true

logging.level.org.hibernate.type.descriptor.sql=trace

logging.level.org.hibernate.type.descriptor.sql.BasicBinder=trace


spring.mvc.format.date=dd-MM-yyyy
spring.mvc.format.date-time=dd-MM-yyyy HH:mm
spring.mvc.format.time=HH:mm:ss

spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

spring.jackson.serialization.indent_output=true

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>ru.terentyev</groupId>
    <artifactId>TaskManager</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>TaskManager</name>
    <description>Web + REST Task Manager</description>
    <properties>
        <java.version>20</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity6</artifactId>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
             <groupId>com.fasterxml.jackson.datatype</groupId>
             <artifactId>jackson-datatype-hibernate6</artifactId>
        </dependency>
            </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Скажите, если надо добавить что-то еще из кода.


Ответы (0 шт):