I am working on the Spring Framework. and made one junit class
but i am not able to properly load the xml files needed to run the #Test method in junit class. In my case
xml file are placed under folder WEB-INF
the junit test class is under test/<package_name>
Please suggest me right way to declare the xml files in
#ContextConfiguration
#ContextConfiguration( locations={ "classpath:/applicationContext.xml",
"classpath:/applicationDatabaseContext.xml" })
Error :
Caught exception while allowing TestExecutionListener
[org.springframework.test.context.support.DependencyInjectionTestExecutionListener#48fa48fa]
to prepare test instance [] java.lang.IllegalStateException: Failed to
load ApplicationContext
If you are using Maven (recommended) then placing your Spring configuration files in the standard location src/main/resources (and src/test/resources for any test-specific configuration), then during the build these files will be copied to the target/classes directory.
You can reference these in your #ContextConfiguration with simply:
#ContextConfiguration(locations = { "/applicationContext.xml",
"/applicationContext-test.xml"})
If you're not using Maven, I'd still recommend using the Standard Directory Layout for source and artifacts, and making your (presumably Ant-based) build process work in a similar manner.
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?
I'm using Spring Boot 2 and I'm trying to do an integration test.
I configured a custom application.properties this way:
#TestPropertySource(
locations = "classpath:###/$$$/application-integrationtest.properties"
)
#ComponentScan(basePackages = { "###.$$$" })
File is under src/test/java/###/$$$/application-integrationtest.properties
Running Junit under Eclipse works fine, but if I try gradle test, I get:
java.io.FileNotFoundException: class path resource
[###/$$$/application-integrationtest.properties] cannot be opened
because it does not exist
What's the deal?
Ok, I put my property file under src/test/resources and added the folder to the build path in Eclipse.
PS: my previous answer was wrong. If I name the file application.properties, the default one has the precedence and it's loaded instead of the test one.
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 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.
I'm using maven war plugin to build war package.
Before package is build test are executed. To preinitialize my database with sample data I use spring bean. I would like to have different data in my db for tests and different when application starts.
I was thinking that maybe it is possible to use two different spring initializer classes in 'test' and 'war' phases but I don't know how to achieve this.
You have to put the different classes you need into src/main/java or src/test/java or may be supplemental application.xml into src/main/resources or src/test/resources. The test initializer can be done by a Test class which initializes first before all tests are running (take a look at testng which has this kind of feature).
Your tests should not be using the production Spring context (xml) files.
Instead, if you need to access an ApplicationContext in your tests (or if you are using a base testcase class like AbstractTransactionalJUnit4SpringContextTests), set up a test-context.xml context which points to the test database configuration and the test data scripts.