Spring Boot тесты и Джексон - получите экземпляр ObjectMapper из настроек контекста (application.yml) в тестах без дополнительной настройки - PullRequest
0 голосов
/ 30 сентября 2019

Я хочу знать, как лучше всего получить экземпляр ObjectMapper из настроек контекста в application.yml без конфигурации «накладных расходов» (что означает WebAppConfiguration и ContextConfiguration) в Spring Boot, только сминимальное количество классов для загрузки в тестах.

Я уже знаю, что для загрузки конфигурации, связанной с Джексоном, в application.yml (spring.jackson.xxx) необходимо @Autowired a Jackson2ObjectMapperBuilder и использоватьbuilder.build() чтобы получить ObjectMapper.

Итак, я создаю класс конфигурации:

@Configuration
public class JacksonConfig {
    @Autowired
    private Jackson2ObjectMapperBuilder objectMapperBuilder;

    @Bean
    public ObjectMapper objectMapper() {
        return objectMapperBuilder.build();
    }
}

И класс оболочки:

@Service
@Slf4j
public class JsonConverter {

    @Getter
    @Autowired
    private ObjectMapper mapper;

    public String objectToJson(Object obj) {
        try {
            return mapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            log.error("Cannot serialize object {} to JSON", obj);
            throw new ServiceException(ErrorCode.JSON_CONVERTER_EXCEPTION)
                    .addLog("log", e.getMessage());
        }
    }

    public Object jsonToObject(Class c, String json) {
        try {
            return mapper.readValue(json, c);
        } catch (IOException e) {
            log.error("Cannot deserialize JSON as instance of class {}", c.getName());
            throw ServiceException.wrap(e, ErrorCode.JSON_CONVERTER_EXCEPTION)
                    .addLog("json", json)
                    .addLog("target class", c.getName());
        }
    }

    public String messageErrorToJson(String message) {
        Map result = Collections.singletonMap("responseError", message);
        return objectToJson(result);
    }
}

Это работает в gradle bootRun, а также в таких тестах:

@Slf4j
@SpringBootTest // we can only launch the whole context to make Jackson2ObjectMapperBuilder to work
@WebAppConfiguration
@ContextConfiguration
class JsonConverterTest {

    @Autowired
    private JsonConverter jsonConverter;

    ...

Я знаю, что это работает, потому что при отладке он останавливает точку останова в JacksonAutoConfiguration классе.

Но, мне интересно, есть ли другой более простой способ получить его. Почему я должен использовать @WebAppConfiguration и @ContextConfiguration? Почему @SpringBootTest не загружает значения application.yml spring.jackson.xx?

Или, чтобы убедиться, что application.yml загружен, как ограничить загрузку классов в SpringBootTest, чтобы минимизироватьколичество классов для загрузки и ускорения тестов?

EDIT: если я удаляю @WebAppConfiguration и ContextConfiguration и добавляю @SpringBootTest(class = MyApplication.class), он также загружает весь контекст / запускает все приложение и работает,

Ответы [ 2 ]

0 голосов
/ 01 октября 2019

Я нашел две вещи:

В @SpringBootTest, только когда я добавляю classes = MyApplication.class, конфигурация Джексона будет загружена и Jackson2ObjectMapperBuilder не нужна. Без этой части выполнение этого теста работает исключительно, но если я запускаю gradle test, все остальные тесты работают, кроме этого. Некоторое кеширование контекста играет здесь роль ... Я не знаю почему.

В любом случае, похоже, что нет другого пути, кроме другого ответа и добавления MyApplication.class.

0 голосов
/ 30 сентября 2019

Давайте начнем с вашей последней точки

Если я удаляю @WebAppConfiguration и ContextConfiguration и добавляю @SpringBootTest (class = MyApplication.class), он также загружает весь контекст / запускает все приложениеи работает.

Пожалуйста, проверьте эту ссылку , с пружинной загрузкой 1.4 и далее @SpringbootTest можно использовать вместо @ContextConfiguration (и некоторых других аннотаций теста)

@WebAppConfiguration следует использовать, только если вы хотите, чтобы веб-часть вашего приложения была инициализирована. Например, если вы хотите проверить свои контроллеры, используя MockMvc и так далее.

Не уверен, почему вы спрашиваете, загружает ли тест springboot application.yml, вы пытаетесь загрузить какие-либо свойства оттуда во время теста (я не вижу здесь).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...