I'm struggling with JUnit 5 when moving the #SpringBootApplication to a different package.
I have setup a new SpringBoot-project (2.2.1.RELEASE) with Maven and Eclipse (had to upgrade this from "Eclipse Photon" to support the SpringBoot-Release
My package layout looks like this:
/src/main/java
com.package.sample.appl1
StartSamples.java
com.package.sample.appl1.start
com.package.sample.appl1.dbaccess
com.package.sample.appl1.run
com.package.sample.appl1.utils
com.package.sample.appl2.run
com.package.sample.appl2.run
/src/test/java
com.package.sample.appl1.dbaccess
SimpleTest.java
The class holding the #SpringBootApplication is:
#ComponentScan({
"com.package.sample"
})
#SpringBootApplication
public class StartSamples {
public static void main(String[] args) {
System.out.println("Start");
try {
SpringApplication.run(StartSamples.class, args);
} catch (Exception e) {
LOGGER.error("", e);
System.exit(-1);
}
}
And the test is this:
import static org.junit.Assert.assertEquals;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.test.context.junit.jupiter.SpringExtension;
/**
* Test the Query-statements and the DAO methods
*
* #author U005078
*
*/
#SpringBootTest
#ExtendWith(SpringExtension.class)
#ComponentScan({
"com.package.sample"})
#EnableAutoConfiguration
public class SimpleTest {
#SuppressWarnings("unused")
private static final Logger LOGGER = LoggerFactory.getLogger(SimpleTest.class);
#Test
#DisplayName("SimpleTest")
public void testTotalRows() {
With this configuration all is fine, "StartSamples" works as expected and aqlso the SimpleTest.
But when moving "StartSamples" to a different package (e.g. "com.package.sample.start" would make more sense to me - "StartSamples" is still ok but "SimpleTest" does not fail nor succeed - test seems not to become executed.
I see a message:
class path resource [com/package/sapmle/appl1/dbaccess/SimpleTest-context.xml] does not exist
class path resource [com/package/sapmle/appl1/dbaccess/SimpleTestContext.groovy] does not exist
.SimpleTest]: SimpleTest does not declare any static, non-private, non-final, nested classes annotated with #Configuration.
I also found:
Neither #ContextConfiguration nor #ContextHierarchy found for test class [com.package.sample.appl1.dbaccess.SimpleTest], using SpringBootContextLoader
So I defined the #ContextConfiguration to the "SimpleTest", then it worked. But I do not understand at all why the move of the #SpringBootApplication did change this behaviour.
With another try of setting up this project I ended up with "No tests found with test runner 'JUnit 5'" and could also not find any reason. I started over again with the current approach and get to here. And do do nat any clue what gives me the error - for either of the problems.
Any explanation witld be appreciated. I tried for lots of hours now to find something in the internet - but I only found recommendations like "try this", "try that" but no help in understanding.
So any help is appreciated.
Define your SpringBoot Main class like below
#SpringBootTest(classes = {StartSamples.class})
public class SimpleTest {
...
}
I want to use the command "mvn spring-boot:run" but I want to use it with some arguments or something that allows me to use only DemoApplication.java and runs the project without any errors. Warnings are NOT a problem.
I cannot delete the other #SpringBootApplication Annotated file named SecureAppApplication nor change its content. (Courtesy of a strict Professor with unreasonable demands)
Here is the relevant error message after executing command:
mvn spring-boot:run
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-
maven-plugin:2.1.8.RELEASE:run (default-cli) on project myproject:
Execution default-cli of goal org.springframework.boot:spring-boot-
maven-plugin:2.1.8.RELEASE:run failed: Unable to find a single main
class from the following candidates
[com.example1.example1.DemoApplication,
com.example1.example1.secureapp.SecureAppApplication]
Here is the DemoApplication file code:
package com.example1.example1;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
System.out.println("System is working!");
}
}
Here is the SecureAppApplication.java file code:
package com.example1.example1.secureapp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
#SpringBootApplication
public class SecureAppApplication {
public static void main(String[] args) {
SpringApplication.run(SecureAppApplication.class, args);
}
}
From the command line, you can specify the main class that you want to execute
mvn spring-boot:run -Dstart-class=com.your.package.application.BookApplication
When running JUnit testing , it gave an initializationError: No tests found matching. Like this:
prodapi-main-junit
initializationError(org.junit.runner.manipulation.Filter)
java.lang.Exception: No tests found matching [{ExactMatcher:fDisplayName=testCreateSite], {ExactMatcher:fDisplayName=testCreateSite(com.company.product.api.web.rest.HostControllerTest)], {LeadingIdentifierMatcher:fClassName=com.company.product.api.web.rest.HostControllerTest,fLeadingIdentifier=testCreateSite]] from org.junit.internal.requests.ClassRequest#3c0f93f1
at org.junit.internal.requests.FilterRequest.getRunner(FilterRequest.java:40)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createFilteredTest(JUnit4TestLoader.java:77)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:68)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:43)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:444)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
While the testing code is as below:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = ProductApplication.class)
#WebAppConfiguration
public class HostControllerTest{
#Test
public void testCreateSite() throws Exception {
......
}
}
It should be fine to load the class, running well. There're other modules similar with this one, they're fine to run.
I have checked the possible causes:
someone said that missing "Test" annotation result in this error.
While the code did have the annotation as you can see.
some said the build path should be configured to do the build under the testing source folder, getting the testing class, and export.
And that configuration I double-checked worked as well.
maybe testing classes are not generated in the compile time, while I can see those testing classes under the destination folder.
I don't know whether there're any other possible things can get Junit testing error like this. Maybe I should check the class loader?
After googled some answers. I found there's an issue talked about this case as below:
https://github.com/junit-team/junit4/issues/1277 (FilterRequest may hide the real failure cause(exception) of a test)
Here're the steps I tried:
1. don't select the testing function alone, while select "Run all the tests in the selected project" option on the Test Tab, when select the Junit project name
after click on Run->"Run(Debug) Configuration"
2. You can get the details of the error as follows:
initializationError(com.company.product.api.web.rest.HostControllerTest)
java.lang.Exception: Method testSetDBConfiguration should have no parameters
at org.junit.runners.model.FrameworkMethod.validatePublicVoidNoArg(FrameworkMethod.java:76)
at org.junit.runners.ParentRunner.validatePublicVoidNoArgMethods(ParentRunner.java:155)
3.according to the details given by eclipse above, I removed the argument of that function, the initializedError just disappeared.
So this issue rises due to the new added testing function has unnecessary input argument.
The incorrect code :
#Test
public void testSetDBConfiguration(String name) throws Exception {
Changed to
#Test
public void testSetDBConfiguration() throws Exception {
Had the same issue with PowerMock #RunWith(PowerMockRunner.class) then discovered that my #Test was the wrong implementation. Was using
import org.junit.jupiter.api.Test;
I switched to import org.junit.Test; and that fixed the problem for me.
I have found the below solution which worked for me.
your Application #SpringBootApplication package name
and Test package name should be same .
see if it helps.
Happy coding.
First able Make sure that your methods annotated #test as well as the test class are public.
I had a similar error when my test method was private. It needs to be public.
I had the similar problem and later realized that my main spring boot application configuration was not scanning through the packages that had my test classes in
Main class was scanning packages - {"com.mycmp.prj.pkg1", "com.mycmp.prj.pkg2", "com.mycmp.dependentprj.pkg5"}
Test class was in package - com.mycmp.prj.pkg3
Problem got fixed by fixing our base packages to scan all packages from current project and only scan limited needed packages from dependent libraries
Main java class
#SpringBootApplication(scanBasePackages = {"com.mycmp.prj.pkg1", "com.mycmp.prj.pkg2", "com.mycmp.dependentprj.pkg5"})
public class MyApplication extends SpringBootServletInitializer {
public static void main(final String[] args) {
SpringApplication.run(MyApplication.class, args);
}
#Override
protected SpringApplicationBuilder configure(final SpringApplicationBuilder application) {
return application.sources(MyApplication.class);
}
#Bean
public FilterRegistrationBean<Filter> customFilters() {
final FilterRegistrationBean<Filter> registration = new
FilterRegistrationBean<>();
final Filter myFilter = new ServicesFilter();
registration.setFilter(myFilter);
registration.addUrlPatterns("/myurl1/*", "/myurl2/*");
return registration;
}
#PostConstruct
public void started() {
//
}
}
My Test Class
**package com.mycmp.prj.pkg3;**
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.mongodb.MongoClient;
#RunWith(SpringRunner.class)
#SpringBootTest(classes = MyApplication.class)
public class MongoConfigStoreTest {
#Test
public void testConnection() throws Exception {
final MongoClient client = new MongoClient("localhost", 127027);
assertNotNull(client);
assertNotNull(client.getDatabase("localhost"));
}
}
I had to add the hamcrest-all-1.3.jar into classpath to run unit test.
junit 4.12
java.lang.Exception: No tests found matching [{ExactMatcher:fDisplayName=myTest], {ExactMatcher:fDisplayName=scannerTest(example.JavaTest)], {LeadingIdentifierMatcher:fClassName=example.JavaTest,fLeadingIdentifier=myTest]] from org.junit.internal.requests.ClassRequest#38af3868
at org.junit.internal.requests.FilterRequest.getRunner(FilterRequest.java:40)
Check for below conditions:
Have you used org.junit.jupiter.api.Test; instead of org.junit.Test;
for running Junit 4 test cases?
Have you passed an argument to the
test method as shown below:
public void test(String arg){
assertTrue(true);
}
Re-building a project will also work:
mvn clean install
If it is a maven project run eclipse:eclipse as a Maven build.That resolved my problem.
When you use gradle (and you use codium as IDE)
you may need to rebuild it manually, e.g. with ./gradlew build.
Yup, in VSCode Testing view, I often get the horrible red "InitializationError" for my Java JUnit-based JPA tests and could never figure it out. Based on Mohit Basak comment, I changed
#SpringBootTest(classes = {MyApp.class})
public class MyTest {
...
}
to
#SpringBootTest(classes = {com.xyz.MyApp.class})
public class MyTest {
...
}
and so far I think it's working better now. The tests always ran green/complete and even runs fine from command line with gradle build
I have a data project and UI project. Both projects are Spring Boot applications. Both projects have the same root package (com.myorg) with a main class annotated with #SpringBootApplication.
Data project's main class is:
package com.myorg;
#SpringBootApplication
public class DataApplication {
public static void main(String[] args) {
SpringApplication.run(DataApplication.class, args);
}
}
The UI project's main class is:
package com.myorg;
#SpringBootApplication
public class UiApplication {
public static void main(String[] args) {
SpringApplication.run(UiApplication .class, args);
}
}
The UI project depends on the data project via the following Gradle dependency:
dependencies {
compile('com.myorg:data:1.0')
}
If I run the UI application, it runs without issue. However, if I run an integration test within the UI application such as follows:
package com.myorg
#RunWith(SpringRunner.class)
#SpringBootTest
public class UiIntTest {
#Test
public void contextLoads() {
}
}
The following initialization error occurs:
java.lang.IllegalStateException: Found multiple #SpringBootConfiguration annotated classes
In the data project's main class, if I replace #SpringBootApplication with
#Configuration
#EnableAutoConfiguration
#ComponentScan({ "com.myorg" })
I get the following initialization error when trying to run its integration tests:
java.lang.IllegalStateException: Unable to find a #SpringBootConfiguration, you need to use #ContextConfiguration or #SpringBootTest(classes=...) with your test
For example, if I try to run:
package com.myorg
#RunWith(SpringRunner.class)
#SpringBootTest
public class DataIntTest {
#Test
public void contextLoads() {
}
}
How can I properly configure the data and UI projects?
You need to specify which Spring Boot Main class to use along with #SpringBootTest:
#SpringBootTest(classes = YourUiSpringBootApp.class)
You shouldn't have two SpringApplication annotations in the same package.
Package one.
twoapps.one;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication(scanBasePackageClasses = {One.class})
#EnableAutoConfiguration
public class One extends SpringApplication {
}
Package two.
twoapps.two;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication(scanBasePackageClasses = {Two.class})
#EnableAutoConfiguration
public class Two extends SpringApplication {
}
Root package and launcher
package twoapps;
import org.springframework.boot.SpringApplication;
import twoapps.one.One;
import twoapps.two.Two;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Application {
public static void main(String[] args) throws Exception {
new Thread(() -> SpringApplication.run(One.class, args(args, "--spring.profiles.active=one"))).start();
new Thread(() -> SpringApplication.run(Two.class, args(args, "--spring.profiles.active=two"))).start();
}
private static String[] args(String[] args, String s) {
List<String> collect = Arrays.stream(args).collect(Collectors.toList());
collect.add(s);
String[] strings = collect.toArray(new String[]{});
return strings;
}
}
This is a terrible idea. please don't do it. It is much better to have two different projects and a common project.
I have the following test class and it cannot find the main class for spring-boot. I am using gradle and had this working fine when I was using maven so I have a suspicion it has something to do with Gradle.
I have made the project more modular so they're several boot projects. Example"
service-module and domain-module. I am currently testing my service module
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest(classes = ServiceApplication.class )
#TestPropertySource(locations = "classpath:application.properties")
#Transactional
public class ApplicantImplTest {
However it is unable to resolve ServiceApplicantion.com
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class ServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceApplication.class, args);
}
}
ServiceApplication is located under src->main->java
In my gradle I have:
description = ''
dependencies {
compile project(':util')
compile project(':domain')
}