JUnit Error: "Failed to load ApplicationContext" - java

Nothing seems to work
I'm trying to run simple test:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"/applicationContext.xml"})
#Transactional
public class EmailServiceTest {
I've also tried:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"src/main/webapp/WEB-INF/applicationContext.xml"})
#Transactional
public class EmailServiceTest {
Along with a few different things in place of "location," such as "classpath" and "file."
The "ApplicationContext" is located:
src
main
webapp
WEB-INF
applicationContext.xml
But JUnit test still says: Failed to load ApplicationContext

The issue was solved after we realized our build file was missing information pertaining to testing. Information such as the "app.properties" and " applicationContext" were not being copied into the testing resources. So technically, none of these were on the classpath.

"Failed to load ApplicationContext" can happen due to other reasons. Go through the stacktrace and find the cause of this error.
In my case, I got this error because I had a typo in the application context xml file name.

you need to use #ContextConfiguration(locations = { "file:./src/main/resources/ApplicationContext.xml" }) after #RunWith(SpringJUnit4ClassRunner.class). and test.java file create at /src/test/java/your-package-name.

You have to specify an application context location on the classpath. src/main is added to the classpath. Therefore, you need to specify only webapp/WEB-INF/applicationContext.xml as follows: #ContextConfiguration(locations = {"webapp/WEB-INF/applicationContext.xml"}).

Related

Spring boot: How to read resource from classpath in unit test

I'm trying to read a file from classpath like this in my unit test:
#Value("classpath:state.json")
Resource stateFile;
I have state.json file in src/test/resources directory.
When I try to read this file using stateFile.getInputStream(), it doesn't return any contents. What am I doing wrong?
My test class is annotated like this
#RunWith(SpringRunner.class)
#SpringBootTest
I can see that the code fails if I try with a incorrect file. So I think its seeing the file in classpath but for some reason not reading contents.
I just ran into this. I'm using Maven. I took a look at my target/test-classes folder and my resource file wasn't in there (even though it was in my src/test/resources folder).
I ran mvn clean install and then rechecked my target/test-classes folder and the resource file was now there. After that, my test was able to find the file and the test worked.
So it seems that your resources aren't copied until you do a mvn clean. JUnit is looking in the classpath built by maven and until the file actually makes it into the target/test-classes folder, JUnit won't be able to find it.
You cant access a #Value resource unless its a property defined.
It should be this way.
#Value("${stateJsonPath}")
Resource stateFile;
If you have to get the resource from hardcoded path then use this way.
Resource stateFile = new ClassPathResource("state.json");
Sharing the working solution for posterity. Files present in the classpath can be read using org.springframework.core.io.ResourceLoader. For instance, I have a sample data file called posts.json under directory src/test/java/resources/data and I have to load it during the test case execution as part of #Before
#ActiveProfiles("test")
#ExtendWith(SpringExtension.class)
#SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class SampleTest {
#Autowired
private ResourceLoader resourceLoader = null;
#BeforeEach
void init() {
File dataFile = resourceLoader.getResource("classpath:data/posts.json").getFile();
...
...
}
}
NOTE: the file should present in the classpath when you use the classifier classpath:
This should simply work, notice that the path starts with a dot, indicating current directory;
#Test
public void testFile() {
String path = "./src/test/resources";
String fileName = "test.zip";
File file = new File(path, fileName);
assertTrue(file.exists());
}

Loading the same properties(yml) files in testing enviornment?

I am trying to figure out whether I can load the same .yml property files in testing environment as I load in real.
For example I have a test:
\src\test\java\security\TokenTest.java
Annotated with:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = Application.class)
#WebAppConfiguration
#DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
#ActiveProfiles("dev")
Then I have:
\src\main\resources\application.yml
When I run the application, the environment picks up property-source from the yml location.
Whenever I run my test, the environment does not see this file - i.e. property-source is not created/populated.
The obvious solution is to put duplicate file to the test location:
\src\test\resources\application.yml
And it will load, but that is bad - in terms that it raises unnecessary confusion when perceiving the difference between test and main resources.
This previous problem gets enhanced if you have configuration file per environment.
Is there a way to load resources from src/main/resources for tests?
This is probably some basic classpath scanning concept which I don't know.
My case is that I already faced the nightmare when you have 5 yml properties files per enviornment in src/main/resources and then you have 5 corresponding yml properties files in src/test/resources and someone from your team WILL 100 % at some point introduce discrepancy between them making everyone else bleed in the long term.
So by any means tests must refer to the same configuration files not to be the lost within its own void context.
Solution: Try to "rebuild" the project.
Is there a way to load resources from src/main/resources for tests?
It works for me. Maybe your IDE is not copying changes to the output directory on save or something (I have heard IntelliJ users have to switch that feature on)?
I had the same problem as you, but I figured out that it was a classpath problem in my run configuration in intellij, when setting that up like it should have been it worked as a charm loading application.yml from the main/resources.

how to load application-context.xml using #ContextConfiguration annotation

My project structure is as below:
src/main/java -> contains java classes
src/main/resources/spring/context/application-context.xml
src/test/java -> contains J-unit test
I would like to use #ContextConfiguration annotation to load my application-context.xml
How can I load this file and how can I make sure that all beans are loaded?
I tried it using classpath and file. But nothing works for me.
I am confused when to use classpath and file. Some one please help me with this.
Thanks in advance.
#ContextConfiguration("classpath:/spring/context/application-context.xml") should work.
In conventional Maven project layout, src/main/resources contains classpath resources, therefore you should use classpath: or no prefix at all, because classpath: should be a default one in this case.
If it still doesn't work, perhaps something is wrong with your project configuration and files from src/main/resources doesn't appear in the classpath.
If context loads successfully, all beans in it should be loaded as well, otherwise context will fail to load.
Try with:
ApplicationContext APPLICATION_CONTEXT = new ClassPathXmlApplicationContext("/spring/context/application-context.xml");
If it does not work, try putting application-context.xml directly in src/main/resources and then load it with
ApplicationContext APPLICATION_CONTEXT = new ClassPathXmlApplicationContext("application-context.xml");

Spring Maven unitTest applicationContext loading wrong file

.I have a project that has a spring-config.xml file in src/main/webapp/WEB-INF and an applicationContext.xml file in src/test/resources. I also have an abstract test base class for my unit tests in src/test/java looks something like:
#ContextConfiguration(locations = {"classpath:/applicationContext.xml"})
public abstract class AbstractTestBase extends AbstractTransactionalJUnit4SpringContextTests {
//Common code and fields
}
All my unit tests extends this AbstractTestBase which points to the context within the src/test/resources or should. The problem arises when running my unit tests it is pulling in the spring-config.xml file.
There are other projects my team is working on that have the same file structure, same app context setup, and run as intended, but even when I have each file in the project side by side I don't see where their file runs and this one doesn't.
I am new to spring so I don't know what it is I should be looking for.
Are there any situations where Spring or Maven would not take the app context I'm handing it given all files exist? Is there anything I might be missing?
EDIT: corrected to reflect that one file is a spring-config file.
"classpath:/applicationContext.xml" should look under src/test/resources.
But it should be noticed that using that syntax will load the first one it finds and then stop as mentioned by '#chrylis'.
I once had similar problem.
You must have been using an IDE. There must have been applicationContext.xml file in your target/test-classes/ (in Eclipse IDE) in your project directory that is a copy of your xml file under src/main/webapp/WEB-INF or xml file like it.

How to WEB-INF/spring/webmvc-config.xml configuration in Spring JUnit Tests correct

I have a maven based Spring 3.0 project. The Spring configuration file for the web application is located at /<proj>/src/main/webapp/WEB-INF/spring/webmvc-config.xml.
Now I want to have a JUnit test that checks if the context can be started. But I did not knwo how to specify the location of that file in the #ContextConfiguration tag in a maven correct way.
I am doing:
#RunWith(SpringJUnit4ClassRunner.class)
#Transactional()
#ContextConfiguration({
"classpath:META-INF/spring/application-context.xml",
"file:src/main/webapp/WEB-INF/spring/webmvc-config.xml",
})
public class SpringMvcContextTest {
But I am pretty sure that I should not refer to the maven src directory.
If you are on maven why don't you choose resource directory for this, and use classpah:file.xml

Categories