How to use #JsonTest when there is no #SpringBootApplication? - spring-boot

I want to use #JsonTest to write tests on JSON serialization for my library. However, when I add the annotation to a test, I get:
Unable to find a #SpringBootConfiguration, you need to use #ContextConfiguration or #SpringBootTest(classes=...) with your test
As this is a library, I indeed don't have a main class annotated with #SpringBootConfiguration. How can I avoid that I need to introduce this just to get the testing framework going?

Seems the only way is to actually add a dummy application. In my case, I added this into src/test/java to avoid it will end up in the production sources. So something like this:
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Just created this here to make #JsonTest work
*/
#SpringBootApplication
public class DummyApplication {
}

#SpringBootConfiguration
#EnableAutoConfiguration
#ComponentScan
public class SpringTestContext {
}
Put this in your library module, located in root test dir, This will supply a ApplicationContext for your tests.

Related

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.

Springboot build not working because of test configuration

I have started a spring boot project using start.spring.io.
But I am getting this error-
I have read various articles on the internet about this issue and they all say about putting my tests in the same package as my Main class.
But I already have the same.
Could you point out what is wrong with my configuration?
The exception is pretty clear: You are missing a configuration for your spring context. What you need to do is to add the configuration classes for your context like so:
#SpringBootTest(classes = { TestConfiguration.class })
whereas your TestConfiguration class must be annotated with
#Configuration
and/or
#EnableAutoConfiguration
There you can add configurations to your liking. You can of course also use your DatabaseApplication class as Configuration although Im wouldn't recommend that.
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 structure your code in a sensible way your main configuration is usually found.
Make Sure your DatabaseApplication class is annotated with #SpringBootApplication .

Unable to find a SpringBootConfiguration in Spring Boot Test 1.4

I'm not able to run a simple test in spring boot 1.4. I followed the tutorial from the official site testing-the-spring-mvc-slice but I didn't get it to work.
every time i get the following error:
java.lang.IllegalStateException: Unable to find a #SpringBootConfiguration, you need to use #ContextConfiguration or #SpringBootTest(classes=...) with your test
any ideas, hints?
Thanks in advance
Edit:
this is the controller
#Controller
public class UserManagementController {
#GetMapping(value = "/gs/users/getUsers")
public #ResponseBody String getAllUsers() {
return "test";
}
}
this is the test
#RunWith(SpringRunner.class)
#WebMvcTest(UserManagementController.class)
public class UserManagementControllerTest {
#Autowired
private MockMvc mvc;
#Test
public void showUserView() throws Exception {
this.mvc.perform(get("/gs/users/getUsers"))
.andExpect(status().isOk())
.andDo(print());
}
}
From my point of view it's exactly the same like this post from the site.
the #WebMvcTest will do:
Auto-configure Spring MVC, Jackson, Gson, Message converters etc.
Load relevant components (#Controller, #RestController, #JsonComponent etc)
Configure MockMVC
now why i need to configure a "super" class
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 structure your code in a sensible
way your main configuration is usually found.
So you have annotated your test with #*Test. It run, checked for configuration in subclasses, haven't found any, thrown an exception.
You have to have a config in a package or subpackage of test class or directly pass config class to #ContextConfiguration or #SpringBootTest or have class annotated with #SpringBootApplication.
According to #SpringBootApplication. I have tested controller in way you have mentioned with #WebMvcTest: it works if application has class annotated as #SpringBootApplication and fails with exception you've mentioned if not. There is remark it the article you mentioned:
In this example, we’ve omitted classes which means that the test will
first attempt to load #Configuration from any inner-classes, and if
that fails, it will search for your primary #SpringBootApplication
class.
Github discussion about the same point.
Spring Boot Documentation

#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.

Is there a way to use Spring #Profile annotation at a package level?

I'm trying to put all my bean definitions for a specific profiles together, and would rather not push them all into one giant AppConfig.java class. I was wondering if there was a way to annotate at a package level using package-info.java and have all configuration files within that package inherit the profile.
I've tried the following in package-info.java:
#Profile("test")
package com.system.configuration.test;
import org.springframework.context.annotation.Profile;
But the #Configuration classes within the package seem to be used whether it is the "test" profile or not.
Is the only choice to annotate each class individually?
You can do it in different way by creating separate #Configuration classes for different profiles:
#Configuration
#Profile("test")
#ComponentScan("com.system.configuration.test")
public class TestProfile {
}
And then on your main configuration class you need to do imports:
#Configuration
#Import(TestProfile.class)
public class MainConfiguration {
}

Resources