I want to know what is the best way to get an instance of ObjectMapper
from context settings in application.yml
without "overhead" configuration(which means, WebAppConfiguration
and ContextConfiguration
) in Spring Boot, with only the minimized number of classes to load in the tests.
I already know that, to load Jackson-related config in application.yml
(spring.jackson.xxx
), you must @Autowired
a Jackson2ObjectMapperBuilder
, and use builder.build()
to get an ObjectMapper
.
So I create a configuration class:
@Configuration
public class JacksonConfig {
@Autowired
private Jackson2ObjectMapperBuilder objectMapperBuilder;
@Bean
public ObjectMapper objectMapper() {
return objectMapperBuilder.build();
}
}
And a wrapper class:
@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);
}
}
That works in gradle bootRun
, as well as in tests like this:
@Slf4j
@SpringBootTest // we can only launch the whole context to make Jackson2ObjectMapperBuilder to work
@WebAppConfiguration
@ContextConfiguration
class JsonConverterTest {
@Autowired
private JsonConverter jsonConverter;
...
I know it works, because when debugging it stops a breakpoint in JacksonAutoConfiguration
class.
But, I wonder if there is another simpler way to get it. Why I have to use @WebAppConfiguration
and @ContextConfiguration
? Why doesn't @SpringBootTest
load the application.yml
spring.jackson.xx
values?
Or, to make sure the application.yml
is loaded, how to limit the classes to load in a SpringBootTest
to minimize the number of classes to load, and speed up the tests?
EDIT:
If I delete @WebAppConfiguration
and ContextConfiguration
, and add @SpringBootTest(class = MyApplication.class)
, it also loads all the context/launch the whole app and works.
Let us start from your last point
If I delete @WebAppConfiguration and ContextConfiguration, and add @SpringBootTest(class = MyApplication.class), it also loads all the context/launch the whole app and works.
Please check this link, with springboot 1.4 and onwards @SpringbootTest
can be used in place of @ContextConfiguration
(and some other test annotations)
@WebAppConfiguration
should be used only if you want the web part of your application to be initialized. For example if you want to test your controllers using MockMvc
and so on.
Not sure why you are asking if springboot test loads application.yml, Are you trying to load any properties from there during Test(I do not see here).