How to test the main Spring-boot application class

I have a spring-boot application where the @SpringBootApplication start class looks like standard. So I created a lot of tests for all my functions and will post my resume to sonarqube to see my scope.

For my senior, Sonarqube tells me that I only have 60% coverage. Thus, the average coverage is not as good as expected.

enter image description here

The My Test class is standard.

 @RunWith(SpringRunner.class) @SpringBootTest(classes = ElectronicGiftcardServiceApplication.class) public class ElectronicGiftcardServiceApplicationTests { @Test public void contextLoads() { } } 

So, how can I test my main class in the starter class of my application?

+40
java spring-boot junit
source share
5 answers

All of these answers seem redundant.
You do not add tests to make the metric tool happy.
Downloading the application spring context takes a lot of time . Do not add it to each build for developers to win about 0.1% coverage in your application.
Here you do not consider only 1 statement from 1 open method. It does not represent anything in terms of coverage in an application where thousands of applications are usually written .

First workaround: create a Spring Boot application class with no declared component inside. If you have them, move them to the configuration class (so that they are still covered by the unit test). And then ignore your Spring Boot application class in the test coverage configuration.

The second workaround: if you really need to cover the main() call (for example, for organizational reasons), create a test for it, but an integration test (performed by the continuous integration tool, and not in each developer build) and clearly document the purpose of the test lesson:

 import org.junit.Test; // Test class added ONLY to cover main() invocation not covered by application tests. public class MyApplicationIT { @Test public void main() { MyApplication.main(new String[] {}); } } 
+44
source share

You can do something like this

 @Test public void applicationContextLoaded() { } @Test public void applicationContextTest() { mainApp.main(new String[] {}); } 
+12
source share

I had the same goal (to have a test that runs the main () method), and I noticed that simply adding a test method like @ fg78nc actually β€œlaunches” the application twice: once using the spring boot test environment , once through an explicit call to mainApp.main(new String[] {}) , which I do not find elegant.

In the end, I wrote two test classes: one with the annotation @SpringBootTest and an empty test method applicationContextLoaded (), the other without @SpringBootTest (only RunWith(SpringRunner.class) ), which calls the main method.

SpringBootApplicationTest

 package example; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.boot.test.context.SpringBootTest; @RunWith(SpringRunner.class) @SpringBootTest public class SpringBootApplicationTest { @Test public void contextLoads() { } } 

ApplicationStartTest

 package example; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) public class ApplicationStartTest { @Test public void applicationStarts() { ExampleApplication.main(new String[] {}); } } 

In general, the application is still running twice, but because now there are two test classes. Of course, with just these two testing methods, this seems superfluous, but usually more tests will be added to the SpringBootApplicationTest class, taking advantage of the @SpringBootTest installation.

+5
source share
 <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>your.awesome.package.Application</mainClass> </configuration> </plugin> 

If you are aiming for 100% coverage, one thing you can do is simply not having a basic method at all. You still require a class annotated with @SpringBootApplication , but it may be empty.

Be careful, although it has its drawbacks, and other tools that rely on main may break.

+2
source share

You can Mock SpringApplication since this is a dependency on the method being tested. See how here . Those.

 import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import org.springframework.boot.SpringApplication; import static org.powermock.api.mockito.PowerMockito.mockStatic; import static org.powermock.api.mockito.PowerMockito.verifyStatic; @RunWith(PowerMockRunner.class) public class ElectronicGiftcardServiceApplicationTest { @Test @PrepareForTest(SpringApplication.class) public void main() { mockStatic(SpringApplication.class); ElectronicGiftcardServiceApplication.main(new String[]{"Hello", "World"}); verifyStatic(SpringApplication.class); SpringApplication.run(ElectronicGiftcardServiceApplication.class, new String[]{"Hello", "World"}); } } 
0
source share

All Articles