Spring Boot 3.1
On a test class annotated with @JsonTest
I should supposedly only get wired the minimal stuff necessary for JSON serialization/de-serialization testing. Not so.
I have my main application class annotated as follows:
@SpringBootApplication
@EnableJpaRepositories(considerNestedRepositories = true)
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
The @EnableJpaRepositories
annotation causes the JsonTest to attempt to start all of the JPA stuff, even if that is not the intention. This is documented here. There is also this ticket which is closed without further comments.
What are my options? I need the @EnableJpaRepositories
annotation because I need the considerNestedRepositories
setting. So I cannot just leave it out.
The answer was in the Spring Boot guide: I have to remove such annotations from the main class of the application.
My main class is now "clean" :
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
I then have a bunch of "@Configuration" files, one for each area of the application. For example I have one for Jackson, one for JPA, one for Swagger, etc. This separation of the config makes it easier to perform targeted testing with Spring Boot's @...Test
annotations, like the @JsonTest
annotation.
For example, my configuration file for JPA stuff looks like this:
@Configuration(proxyBeanMethods = false)
@EnableJpaRepositories(considerNestedRepositories = true)
public class JpaConfig {
}
(yes, it is empty, but I might have something to put in there some day, the main point was to have a place to put the @EnableJpaRepositories
annotation.)
The tests using test slicing (like @JsonTest
) do not pick up all my "@Configuration" files, it only auto-detects the application's main class. So in in such tests I therefore have to explicitly pull in (import) the appropriate config, like this:
@JsonTest()
@Import({JacksonConfig.class,JacksonTest.JacksonTestConfig.class})
public class MyJacksonTest {
...
}
Here I pull in the application's general Jackson config (the JacksonConfig
class). In addition I pull in some additional config, JacksonTest.JacksonTestConfig
, which lives in the test tree. All in all, using this technique I can "compose" what config I want to have added to my test.
The morale is: Keep your main class free of config-related annotations, in particular if they apply to an area that you may not want to have applied with sliced testing. The unfortunate thing is that the Internet is full of recommendations where people will say: "just add this annotation to your main class" ... but this is not always a good idea.