This article and the source codes attached should be used as reference only.Please thoroughly test your implementation before making changes to production environment
Checkout our NEW Video Channel you can like and subscribe too!

Introduction

As testing is an important aspect of any application, SpringBoot comes with a wide variety of unit,integration and functional testing.

Integration test

Source Code

@SpringBootTest with WebEnvironment.RANDOM_PORT is the simplest way of doing a sanity test of the APIs but this starts a whole application server on a random port.To avoid running a full application stack use it with combination of @AutoConfigureMockMvc and autowire MockMvc. In this way we get the full stack and behave as real http request processing without the cost of starting the server.

In any case,note that integration test cases are time consuming and should be avoided in production environments.

@ActiveProfiles should be set to test. When running this testcases. Also the Integration testcase should be suffixed with IT at the last,this enables fail safe plugin to pickup IT test case only and ignore unit test cases.

@FixMethodOrder use is only if necessary , because its sets the order of the test case in alphabetical order.Might be helpful when checking sequence of test cases.

While testing cases where spring security needs to be used,incases of authentication of user or token,use the @Before annotation and stage the mockMVC and inject webApplicationContext and springSecurityFilterChain.This will add the security filters to the test class for Spring login or OAuth2 flows.

Need to annotate the class with @TestConfiguration incase we need to load some configuration beans at startup for the testcase to run.This is similar to @Configuration when main application runs.

All the IT test case runs an in memory database that load on startup. Because in memory database is difficult to debug, we use the file based in memory database so that we can login to the database using our choice of database editor and look for issues.The data.sql and schema.sql are the schema files that brings up and db and stage the test data.

Use data.sql for staging the data as per the test case scenario.We are free to modify the data as this runs on completely isolated h2 database unlike the main database with runs on postgres.

1.CoreOAuth2FrameworkTestIT - this class tests the core features of Spring OAuth2 which includes password grant type,checktoken endpoint,token validity,token revocation etc.This class needs to pass always and especially during the Spring module updates.

2.LoginTestIT - This class takes care of user login and account login features.This is important testcase to run on every build

3.ResourceControllerRestIntegrationTestIT - This class does vatal integration scenarios like the token generation happens with correct scopes,user creation happens and is persisted.This IT class goes till the dept of record in the database.This should be run when there in api change.

Unit test

@WebMvcTest only test the web layer.This is considerably much faster than spring boot test and can be executed in each release.This does by slicing only the web layer and not loading entire spring context.Use it with combination with AutoConfigureMockMvc to mock mvc calls. Also specific the controller class we are using to test,in that way we load only the controller we are interested in.This done by passing the class in the @WebMvcTest(value = ResourceController.class).

Another type of Unit test that falls under this category is standard Junit test with SpringRunner.class annotation.

ResourceControllerMVCTest - This class test all the api endpoints and covers every fail/pass scenarios.If we modify the service layer we need to modify the test case here.@WebMvcTest is used in combination with @MockBean.Mock the service layer.

UserServiceTest - In this case we have to annotate the class with @RunWith(SpringRunner.class) and also add also @TestConfiguration in a static class with mock beans of all the injected classes.Only the service class we want test we need to instantiate a bean of that class.Note that as we dont annotate with @SpringBootTest and @AutoConfigureMockMvc so we dont load @configuration here.We defined all configuration under @TestConfiguration.Craft the test mvc class correctly to place the mock beans and autowire them and then use Mockito to mock the repository layer and test the service layer.

Guidelines to use test annotations

springboot-test-types.PNG

CodeQuality & Coverage

We use Jacoco and SonarQube for code quality checks.Jacoco provides us the coverage reports which is then loaded in SonarQube to go through Quality rule checks.Below are the checks done

image54.png

We use maven-surefire-plugin to perform unit tests

image55.png

Failsafe plugin is used for integration testing

image56.png

Both of these testings happens when Spring profiles is set to TEST and also we can switch on/off these testing

mvn test failsafe:integration-test -Dintegration-tests.skip=false -Dunit-tests.skip=false

If Dintegration-tests.skip or Dunit-tests.skip is set to false,then all test case are executed.

Once the data is loaded into SonaQUbe look for the following checks

1.Bugs - Bugs should be zero always.They shouldnt be ignored 2.Code Smells - Code Smells are good to be removed to follow naming conventions and other aspects.Keep them below 20 at least.Sometime it is hard to manage this.If you want to avoid a rule being applied to a particular method

@java.lang.SuppressWarnings(“squid:S3776”) where squid is rule id

3.Coverage - This tells how much of the code is testable.Very important to avoid stale unused code or unreachable code.We should target to meet above 93% coverage.Some of the packages can be ignored from coverage

image57.png

    Content