Learn to write Junit tests in spring boot applications. Also learn to use RestTemplate to invoke REST APIs and verify test results in success and error scenarios in this spring boot junit tutorial.
To create the rest apis, use the sourcecode provided in spring boot 2 rest api example.
By default, Spring boot uses Junit 4. To write tests in Junit 5, read this migration guide : Junit 5 with Spring boot 2.
1. Maven dependencies
Make sure to have spring-boot-starter-test dependency in the project to be able to execute unit tests.
< dependency > < groupId >org.springframework.boot</ groupId > < artifactId >spring-boot-starter-test</ artifactId > < scope >test</ scope > </ dependency > |
2. Spring boot JUnit Test Class
A Junit test class in Spring boot application can be written like this.
@RunWith (SpringRunner. class ) @SpringBootTest (webEnvironment=WebEnvironment.RANDOM_PORT) public class SpringBootDemoApplicationTests { @LocalServerPort int randomServerPort; @Test public void testGetEmployeeListSuccess() throws URISyntaxException { } } |
Let’s note down important things here.
- @RunWith(SpringRunner.class) – tells JUnit to run using Spring’s testing support. SpringRunner is the new name for
SpringJUnit4ClassRunner
. It enables full support of spring context loading and dependency injection of the beans in the tests. - @SpringBootTest – annotation that can be specified on a test class that runs Spring Boot based tests. It provides ability to start a fully running web server listening on any defined or random port.
- webEnvironment – enables requests and responses to travel over network and mock servlet container is not involved.
- @LocalServerPort – injects the HTTP port that got allocated at runtime.
3. Spring boot JUnit example
In given below example, I will first write the rest api code and then unit test which invoke the rest api and verify api response.
3.1. HTTP GET API
3.1.1. REST API Code
REST API which return the list of all employees in list.
@GetMapping (path= "/employees" , produces = "application/json" ) public Employees getEmployees() { return employeeDao.getAllEmployees(); } |
3.1.2. Junit Test
Junit test with
RestTemplate
which invoke above API and verify the api response code as well as response body.@Test public void testGetEmployeeListSuccess() throws URISyntaxException { RestTemplate restTemplate = new RestTemplate(); URI uri = new URI(baseUrl); ResponseEntity<String> result = restTemplate.getForEntity(uri, String. class ); //Verify request succeed Assert.assertEquals( 200 , result.getStatusCodeValue()); Assert.assertEquals( true , result.getBody().contains( "employeeList" )); } |
3.2. HTTP POST API
3.2.1. REST API Code
REST API which add an employee to employee collection.
@PostMapping (path= "/employees" , consumes = "application/json" , produces = "application/json" ) public ResponseEntity<Object> addEmployee ( @RequestHeader (name = "X-COM-PERSIST" , required = true ) String headerPersist, @RequestHeader (name = "X-COM-LOCATION" , defaultValue = "ASIA" ) String headerLocation, @RequestBody Employee employee ) throws Exception { //Generate resource id Integer id = employeeDao.getAllEmployees().getEmployeeList().size() + 1 ; employee.setId(id); //add resource employeeDao.addEmployee(employee); //Create resource location URI location = ServletUriComponentsBuilder.fromCurrentRequest() .path( "/{id}" ) .buildAndExpand(employee.getId()) .toUri(); //Send location in response return ResponseEntity.created(location).build(); } |
3.2.2. Junit test – success scenario
Junit test with
RestTemplate
which invoke above API and verify the api response code as well as response body.@Test public void testGetEmployeeListSuccess() throws URISyntaxException { RestTemplate restTemplate = new RestTemplate(); URI uri = new URI(baseUrl); ResponseEntity<String> result = restTemplate.getForEntity(uri, String. class ); //Verify request succeed Assert.assertEquals( 200 , result.getStatusCodeValue()); Assert.assertEquals( true , result.getBody().contains( "employeeList" )); } |
3.2.3. Junit test – error scenario
Junit test which expects an error when there is a missing header in the request.
@Test public void testAddEmployeeMissingHeader() throws URISyntaxException { RestTemplate restTemplate = new RestTemplate(); URI uri = new URI(baseUrl); Employee employee = new Employee( null , "Adam" , "Gilly" , "test@email.com" ); HttpHeaders headers = new HttpHeaders(); HttpEntity<Employee> request = new HttpEntity<>(employee, headers); try { restTemplate.postForEntity(uri, request, String. class ); Assert.fail(); } catch (HttpClientErrorException ex) { //Verify bad request and missing header Assert.assertEquals( 400 , ex.getRawStatusCode()); Assert.assertEquals( true , ex.getResponseBodyAsString().contains( "Missing request header" )); } } |
3.3. Execute JUnit tests
Run the class as Junit test and watch for result.
Let me know if you have any query in this spring boot rest controller junit test example.
No comments:
Post a Comment