#EnableAutoConfiguration on test context - spring-boot

I have project where I'm developing a spring auto configuration module.
I'm using a test configuration class (in test classpath),
In this class we are using #EnableAutoConfiguration
#Configuration
#EnableAutoConfiguration
public class MyTestContext {
}
In each of the test classes I'm using it the following way:
#ContextConfiguration(classes = {MyTestContext.class})
it looks like context is created correclty and test pass.
My Question is:
- Is it good practice to use #EnableAutoConfiguration on a test context ?
- what is the real effect of doing so ?

Related

Does #SpringBootApplication scans test folder for configurations?

I've a #SpringBootApplication annotation in main class of my Spring Boot Application with ordinary folders structure (and #SpringBootApplication is one level package upper then beans in other packages)
I defined some #Configuration classes in some packages but under the test folder.
Will #SpringBootApplication autoconfigure it when start application?
Will #SpringBootApplication autoconfigure it when it will be finded by #SpringBootTest (it's also one level upper but in test folder) when test started?
I am not completely sure, but I would say no, #SpringBootApplication does not scan #Configuration classes in your test folder. What you should use instead is #TestConfiguration and then in your #SpringBootTest add #Import(YourTestConfiguration.class). Find an example below:
#TestConfiguration
public class YourTestConfiguration {
#Bean
(...)
}
#SpringBootTest
#Import(YourTestConfiguration.class)
class AppTests {
(...)
}
You can read more about this and check complete examples in the following online resources:
https://reflectoring.io/spring-boot-testconfiguration/
https://howtodoinjava.com/spring-boot2/testing/springboot-test-configuration/

How to make spring boot test app independent of external property source?

I am writing a controller test for a spring boot application. To use the spring application context I am using SpringRunner class. The problem is the main application class has a property source defined to a specific file path.
When I am running the test I am getting a FileNotFound exception from the hardcoded file. I want my test to be independent of this property source.
I cannot add the 'ignoreResourceNotFound' option for property source in the main application.
Below is the main application class with property source defined.
#SpringBootApplication
#PropertySource("file:/opt/system/conf/smto/management.properties")
#EnableConfigurationProperties
public class ManagementApp {
public static void main(String[] args) {
SpringApplication.run(ManagementApp.class, args);
}
}
I am also adding my test class below
#RunWith(SpringRunner.class)
#TestPropertySource(locations = {"classpath:application.properties","classpath:management.properties"})
#DirtiesContext
#EmbeddedKafka(topics = {"management-dev"},partitions = 1,
controlledShutdown = false,brokerProperties = {"listeners=PLAINTEXT://localhost:9092", "port=9092"})
#AutoConfigureMockMvc
#WebMvcTest(Controller.class)
public class ControllerTest {
}
I have found a workaround to create the spring context in this scenario. I have changed my testing class package and because of it, the spring-boot test cannot find the primary configuration class. And then provided all the required packages to create the application context.
Reference for this solution found from spring docs here.
Spring Boot’s #*Test annotations will search for your primary configuration automatically whenever you don’t explicitly define one.
The search algorithm works up from the package that contains the test until it finds a #SpringBootApplication or #SpringBootConfiguration annotated class. As long as you’ve structured your code in a sensible way your main configuration is usually found.

How to prevent the spring boot application starting for each test classes

I know this question is an old one but I could not solve the problem in my case. When I am running test classes spring boot application is starting for each test class. I am having bellow annotations in my test class files. I want to start the application only once for all test classes
#RunWith(SpringJUnit4ClassRunner.class)
#ActiveProfiles("test")
#SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
#AutoConfigureMockMvc
#WithMockUser
I have achieved this using a parent BaseTest
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
#AutoConfigureMockMvc
public abstract class BaseTest {
}
I use SpringRunner but SpringJUnit4ClassRunner should be ok too
#SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
By using the WebEnvironment.RANDOM_PORT you are telling spring boot to start a server on each class instantiation.
To avoid this, use a parent class that all testclasses extend from.

#ContextConfiguration how to use XML based config and Java-based at same time?

I'm writing integration tests with SpringJUnit4. I got question. How in #ContextConfiguration I can use XML based config and Java-based at same time. As I know I couldn't do it, but maybe there exist backdoor?
Thanks in advance!
You could create static inner #Configuration class in your test class and use #ContextConfiguration annotation on your class without any parameters. As stated in the article below, Spring will automatically look for static inner #Configuration class if no XML locations or config classes are passed to the annotation.
You can then import your XML config and Java config classes using #Import and #ImportResource annotations. So your base class for your Spring tests could look something like this:
#ContextConfiguration
#RunWith(SpringJUnit4ClassRunner.class)
public class BaseSpringTest {
#Configuration
#Import(BaseConfig.class)
#ImportResource({ "classpath:applicationContext-hibernate.xml" })
public static class ContextConfig {}
}
Sources
Testing with #Configuration Classes and Profiles
Import annotation JavaDoc
ImportResource annotation JavaDoc
Use #ImportResource on #Configuration class to import XML based config.

spring java configuration unit test

I am trying out spring's java configuration. While using xml config files my unit tests use to have the following
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(....)
If I am using java configuration, How do i do it. or should I just use
ApplicationContext appConfig = new AnnotationConfigApplicationContext(SimpleConfiguration.class);
As of Spring 3.1, #ContextConfiguration now has full support for #Configuration classes; no XML required.
See http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/htmlsingle/spring-framework-reference.html#d0e1392
Or more specifically, http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/htmlsingle/spring-framework-reference.html#testcontext-ctx-management-javaconfig, which shows the following code snippet:
#RunWith(SpringJUnit4ClassRunner.class)
// ApplicationContext will be loaded from AppConfig and TestConfig
#ContextConfiguration(classes={AppConfig.class, TestConfig.class})
public class MyTest {
// class body...
}
AppConfig and TestConfig are #Configuration classes (aka "Java config" classes in #user373201's comments)
#ContextConfiguration is used to load the Spring configurations while you are working with test cases . If you don't need it , you could use ClassPathXmlApplicationContext to load the Spring configuration .
Use the constructor which takes in configuration locations as String array .
AnnotationConfigApplicationContext is used to auto detect the annotated classes . I don't think it can be used to load configuration files . It is similar to context:component-scan
SpringJUnit4ClassRunner provides Spring Test support for Junit via annotations like #Test.

Resources