Tutorial 6.2: Integration Testing - McGill-ECSE429-Winter2022/tutorials GitHub Wiki

1. Introduction to Spring Boot

1. Spring Framework

  • The Spring framework provides comprehensive support for developing Java applications.
  • Provides the plumbing
  • OOP best practices built-in
  • DRY Principle

2. Why Spring Boot:

  • Supports rapid development
  • Removes boilerplate of application setup
  • Many uses
  • Cloud-native support, but also traditional

Reference to explore more on this topic.

2. Integration Testing

The meaning of Integration testing is quite straightforward- Integrate/combine the unit tested module one by one and test the behaviour as a combined unit. The main function or goal of this testing is to test the interfaces between the units/modules.

Testing Approaches:

1. Bottom Up:

2. Top Down:

Integration Testing Against a Real Database

3. Integration Testing Against Services with Caching Support

Why Service Layer:

  • Separation of concern
  • Loose coupling
  • Orchestration
  • Caching

4. IntegrationTesting Against a Web Controller

e.g: Steps for rest controller:

  • URL Mapping
  • Deserialize Input
  • Validate Input
  • Bussiness Logic
  • Serialize Onput
  • Translate Exceptions

5. Integration Testing For a Client App

6. Demo (Writing Integration Tests for Rest Service)

Overview

Following is the order we do things in this guide:

  • Bootstrap a project using Spring Initializr.
  • Implement a Business Service for our API - StudentService.
  • Implement the API - using StudentController. First, we implement the GET methods and then the POST methods.
  • Write Integration Tests for our API.

1. Creating REST Services Application with Spring Initializr

Spring Initializr http://start.spring.io/ is great tool to bootstrap your Spring Boot projects.
image for spring analyzer
As shown in the image above, the following steps have to be done

  • Launch Spring Initializr and choose the following:
    • Choose com.ECSE429.springboot as Group
    • Choose student services as Artifact
    • Choose the following dependencies
      • Web
      • Actuator
      • DevTools
  • Click Generate Project.
  • Import the project into Eclipse.

Please update your POM file with this sample POM file.

2. Implementing Business Service for your Application

All applications need data. Instead of talking to a real database, we will use an ArrayList - kind of an in-memory data store.
A student can take multiple courses. A course has an id, name, description and a list of steps you need to complete to finish the course. A student has an id, name, description and a list of courses he/she is currently registered for. We have StudentService exposing methods to

  • public List retrieveAllStudents() - Retrieve details for all students
  • public Student retrieveStudent(String studentId) - Retrieve a specific student details
  • public List retrieveCourses(String studentId) - Retrieve all courses a student is registered for
  • public Course retrieveCourse(String studentId, String courseId) - Retrieve details of a specific course a student is registered for
  • public Course addCourse(String studentId, Course course) - Add a course to an existing student

Refer to these files at the bottom of the article for exact implementation of the Service StudentService and the model classes Course and Student.

  • src/main/java/com/ECSE429/springboot/model/Course.java
  • src/main/java/com/ECSE429/springboot/model/Student.java
  • src/main/java/com/ECSE429/springboot/service/StudentService.java

github for the source code.

3. Adding a Couple of GET Rest Services

The Rest Service StudentController exposes a couple of get services.

  • @Autowired private StudentService studentService : We are using Spring Autowiring to wire the student service into the StudentController.
  • @GetMapping("/students/{studentId}/courses"): Exposing a Get Service with studentId as a path variable
  • @GetMapping("/students/{studentId}/courses/{courseId}"): Exposing a Get Service for retrieving specific course of a student.
  • @PathVariable String studentId : Value of studentId from the uri will be mapped to this parameter.

github for the source code.

4. Integration Testing the Get Rest Service

When we are writing an integration test for a rest service, we would want to launch the entire spring context.

  • @SpringBootTest(classes = StudentServicesApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) : Launch the entire Spring Boot Application on a Random Port
  • @LocalServerPort private int port;: Autowire the random port into the variable so that we can use it to create the url.
  • createURLWithPort(String URL): Utility method to create the url given an uri. It appends the port.
  • HttpEntity entity = new HttpEntity(null, headers);: We use entity so that we have the flexibility of adding in request headers in future.
  • restTemplate.exchange(createURLWithPort("/students/Student1/courses/Course1"),HttpMethod.GET, entity, String.class): Fire a GET request to the specify uri and get the response as a String.
  • JSONAssert.assertEquals(expected, response.getBody(), false): Assert that the response contains expected fields.

github for the source code.
Now run and test the service.

⚠️ **GitHub.com Fallback** ⚠️