I started setting tests for my project. It taked a while to settup the context. Now that I have achived it, I am getting trouble to make the tests work on multiple enviroments.
I set up the application test with these anotations:
#ContextConfiguration({"/applicationContext-test.xml", "/appServlet/servlet-context.xml"})
#WebAppConfiguration
#RunWith(SpringJUnit4ClassRunner.class)
#AutoConfigureMockMvc
public class ControllerUserTest {}
The trouble comes from the config file. When running the project on enviroments a parent config file values get replaced by environment ones. For testing for some reason I don't find a way to reproduce this. Meanwhile I setted up the parent config file with develop variables. To resolve this, the parent file was restored and using anotations like #TestPropertySource(properties="env=pre") or #ActiveProfiles("pre"). Neither way the parent file variables are replaced by environment ones. This kind of annotationa allows to change profile from class but It would be intereset to change the envoroment it from command line.
I also tried to use #BeforeClass annotation but the context annotations are executed before it.
To add more info about how the config is read. On "/appServlet/servlet-context.xml" I have a component-scan that points to a package where ApplicationConfig.java is stored . This config has this anotations #Configuration #PropertySource(value = { "classpath:nsf.properties" }).
In which direction I have to investigate to achieve my goal? Thanks in advance
Related
I am writing an integration test that requires (essentially) the whole App Context to run. I have about 20 Context Configuration classes located in packages com.A and com.B. My integration test is located in package com.X. My integration test needs to spin up all Context Configurations in com.A and com.B.
Not having a lot of experience with Spring Boot, I was hoping it would let me simply annotate the test class like this:
#RunWith(SpringRunner.class)
#SpringBootTest()
#ComponentScan(basePackages = { "com.A", "com.B" })
public class AbcIntegrationTest(){
This guess did not work. The test threw an IllegalArgumentException, with the following error:
Unable to find a #SpringBootConfiguration, you need to use #ContextConfiguration or #SpringBootTest(classes=...) with your test
Based on the error message, I tried to replace my #ComponentScan with a #ContextConfiguration. Unfortunately, ContextConfiguration requires a list of Configuration classes, but I need something that can scan the packages containing the Configuration classes. (I have 20-odd classes, and they'll probably be refactored soon. Listing these 20 classes out in ContextConfiguration does not fit my usecase.)
So now I don't know what to do. I started reading the documentation but I haven't found anything that does what I need it to do. Is there any way that my SpringBootTest can load all of the Context Configuration classes in a given package?
Given a spring boot gradle module named "md-core" with a Spring application runner and a PostgresDbConfig to connect it to the DB.
The app runs perfectly fine and resolves the properties from the "application.yml" file in the #Config.
#Value("${db.default.pool.size}")
Integer maxPoolSize;
Now, a separate module called "integrationtests" tries to launch the Spring Boot Runner in the "md-core" module.
#ContextConfiguration(classes = {MdCore.class})
#RunWith(SpringJUnit4ClassRunner.class)
public class GivenTest
The test launches the "md-core" Spring runner, but when trying to resolve the properties in the #Config, it does not find any properties.
I've tried directly resolving the "application.yml" in the test. It does not send the properties over to the "md-core" module. Any attempt of adding the "application.yml" properties in the test resolves them to the test file, but does not send them over when the "md-core" module is accessed.
Are there any definitions which should be given in the test via annotations or in the gradle build files?
The classpath when launching the test does not contain the "md-core" resources location, only the classes.
Could this be a reason? If yes, how can the resources be referenced in the classpath of the gradle build files?
I apologize for any mistakes or incomplete information, this post is being written at the end of a work day, hoping there will be answers by morning.
Given this situation, the solution to use the application.properties file for the integration test is the simple addition of initializers = ConfigFileApplicationContextInitializer.class in the #ContextConfiguration annotation of the Test class:
#ContextConfiguration(
initializers = ConfigFileApplicationContextInitializer.class,
classes = {SomeApp.class})
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
public class SomeIntegrationTest {
#Test
public void testTheIntegration() {
// some integration tests here
}
}
Answer also documented in a post on my blog and initially found less detailed on another stackoverflow question.
I'm having trouble with a Spring Boot app that is not loading a config class with 2 beans in it. The weird thing is that another config class in the same package gets loaded.
Both config classes have #Configuration in them. The one that doesn't load also has a #ComponentScan(basePackages = {"com.example.package.in.jar"}) in it.
The base packages value refers to a package in a loaded jar file.
I'm using Gradle 3.4.1, Spring Boot 1.5.3. When I turn on Spring debugging, it shows the other config class being found and loaded, but it just skips over the other one. No exceptions are thrown - no errors at all.
It would be one thing if the code didn't run, but at least load the class or throw an error, but the log file that was created showed no errors.
Use #EntityScan("com.yourpackage*") will check all the packages starts with "com.yourpackage"
Refer https://github.com/Roshanmutha/JPARepo_44149690/blob/master/src/main/java/com/rcmutha/usl/controller/Application.java
So it turns out that the problem was that it the file wasn't even being seen, period. After attempting the suggestions, I found another option to try: #ImportAutoConfiguration. I used this annotation in the main Spring Boot app file and specified the files in my config package. This is when the compiler said that it couldn't resolve the file I was having problems with.
I cut out the contents, deleted the file and re-created it with a slightly different name, pasted back the contents and update the file list for the annotation. It worked!
The file showed up in the file tree in IntelliJ, but it wasn't being seen by the compiler, so it wasn't being configured. Within the annotation it had to look for it explicitly, and then the error was produced.
Thank you to those that posted suggestions.
Les
I'm running a Spring Boot Application within a Tomcat instance packaged as a war file. I would like to be able to add "packages" to my instance in the form of rest services. To that end I need to be able to configure scanBasePackages in the #SpringBootApplication annotation at runtime. i.e. when tomcat starts up. For now I have ...
#SpringBootApplication(scanBasePackages="path1, path2")
public class RestApplication extends SpringBootServletInitializer {
//code
}
...but I would like to have path2 be configurable and alternately be able to add path3, etc. if desired. How can I achieve this? I understand that I can't configure the String in the annotation so my question is about what other alternatives I have to this annotation for setting this.
Cheers.
you can try to use something like this in your project
#Configuration
#Profile("custom-profile")
#ImportResource( {"file:path/additional-context.xml" } )
public class ConfigClass { }
and configure additional packages scanning in this file then.
<context:component-scan base-package="x.y.z.service, x.y.z.controller, x.y.z.dao" />
Note, your resource additional-context.xml declared as external and you have ability to change it without rebuilding war at all.
#ImportResource will be handled after declaring profile "custom-profile" as active. It's a safe way for starting application with "default configuration" without any "additional-context.xml" file of disk.
Have you tried this:
#SpringBootApplication(scanBasePackages={"path1", "path2"})
Hope this helps :)
I would like to test that a spring
#Configuration class
can handle missing files on the classpath. E.g. when using PropertySourcesPlaceholderConfigurer. But this is just a specific example, the question is really about how to test classes that interact with the classpath (e.g. read a file located in src/main/resources in a maven project).
So in essence I would like to create a spring context where I control the classpath in the test set up code.
The test needs to be a JUnit test.
Hope below may help you
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"classpath*:/testApplicationContext.xml"})
public class YourTestClass{
you have to create a spring context for your test and you can include the production one into it. you can replace classpath*: with a absolute location.
Regards, Rajib.
This work if it's a maven project:
move the classpath file that you want to test the absence from to a separate pom jar module, and include it wherever needed.
move the classpath test to a separate pom jar module named missing-classpath-file-test, but don't include the module with the file that you want to simulate as missing. I will be missing from the classpath only for that test.
When running missing-classpath-file-test, the file will not be on the classpath, and the error you need to reproduce is achieved.
Concerning the question on the comment bellow, with the class loaders that come with application servers and the one used on a junit test it's not possible to programmatically change the classpath.