banner



How To Unittest Spring Boot Service Layer

Spring Boot Unit Testing Service Layer using JUnit and Mockito

In the previous tutorial, we have seen Spring Kicking Unit Testing CRUD Rest API with JUnit and Mockito.  In this tutorial, nosotros will larn how toperform unit testing Spring boot service layer unit testing using JUnit 5 and the Mockito framework.

In order to examination Service layer components, nosotros accept to mock the Repository layer components using the Mockito framework. We don't take to utilize a database for Unit testing.

Check out my Leap boot testing Udemy course: Testing Spring Boot Application with JUnit and Mockito (Includes Testcontainers)

Spring kicking providesbound-boot-starter-exam dependency for unit of measurement testing and integration testing of Spring kick application:

                      <dependency>            <groupId>org.springframework.kicking</groupId>            <artifactId>jump-boot-starter-test</artifactId>            <scope>test</telescopic>            </dependency>                  

The Spring Boot Starter Test dependency is a primary dependency for testing the Leap Kick Applications. It holds all the necessary elements required for the testing.

For the Unit testing service layer, we are going to use the following testing libraries:

  • JUnit five Framework
  • Mockito 4 (Latest)
  • AssertJ Library

JUnit five Framework

It's the de facto standard testing framework for Java.

The current version of JUnit is 5+. The main goal of JUnit v is to support Java viii and above, as well as enable many different styles of testing.

Mockito iv (Latest)

Mockito is a mocking framework. It is a Java-based library used to create elementary and basic test APIs for performing unit of measurement testing of Java applications.

The main purpose of using the Mockito framework is to simplify the development of a test past mocking external dependencies and using them in the test code.

AssertJ Library

AssertJ is a Java library that provides a rich set of assertions and truly helpful error messages, improves test lawmaking readability, and is designed to be super like shooting fish in a barrel to utilise within your favorite IDE.

Spring boot starter exam dependency internally providesassertj-core dependency and so we don't accept to addassertj-core dependency manually in our Spring boot project.

Tools and technologies used

  • Java eleven+
  • Spring Boot
  • Lombok
  • JUnit 5 Framework
  • Hamcrest
  • AssertJ
  • JsonPath
  • Mockito
  • IntelliJ Idea
  • Docker
  • Maven

ane. Create Spring Boot Application

Using leap initialize, create a Leap Kick project and add the following dependencies:

  • Spring Web
  • Spring Data JPA
  • Lombok

Generate the Jump kick project as a zip file, extract it, and import it into IntelliJ Idea.

2. Maven Dependencies

Make certain that y'all have added the below dependencies in your spring boot projection:

                                  <dependency>                  <groupId>org.springframework.boot</groupId>                  <artifactId>jump-kicking-starter-information-jpa</artifactId>                  </dependency>                  <dependency>                  <groupId>org.springframework.boot</groupId>                  <artifactId>spring-boot-starter-web</artifactId>                  </dependency>                  <dependency>                  <groupId>org.projectlombok</groupId>                  <artifactId>lombok</artifactId>                  <optional>true</optional>                  </dependency>                  <dependency>                  <groupId>org.springframework.boot</groupId>                  <artifactId>spring-kicking-starter-test</artifactId>                  <scope>test</scope>                  </dependency>                              

three. Create JPA Entity

Next, let's create anEmployee JPA entity with the following content:

                                                                  import                                            lombok.*;                                              import                                            javax.persistence.*;                                              @Setter                                                                    @Getter                                                                    @AllArgsConstructor                                                                    @NoArgsConstructor                                                                    @Builder                                                                    @Entity                                                                    @Table                      (name =                                              "employees"                      )                                              public                                                                                                                          grade                                                                                                                                                                                Employee                                                                                                                        {                                              @Id                                                                    @GeneratedValue                      (strategy = GenerationType.IDENTITY)                                              private                                            long id;                                              @Cavalcade                      (proper noun =                                              "first_name"                      , nullable =                                              false                      )                                              private                                                                    String                                            firstName;                                              @Column                      (name =                                              "last_name"                      , nullable =                                              false                      )                                              private                                                                    String                                            lastName;                                              @Column                      (nullable =                                              simulated                      )                                              private                                                                    String                                            email; }                  

Note that we are using Lombok annotations to reduce the boilerplate code.

@Entity  annotation is used to marking the class as a persistent Java class.

@Tabular array annotation is used to provide the details of the table that this entity volition be mapped to.

@Id annotation is used to define the principal primal.

@GeneratedValue annotation is used to define the master fundamental generation strategy. In the above example, we have declared the primary key to be an Auto Increase field.

@Column note is used to define the properties of the column that will be mapped to the annotated field. Yous can define several properties like name, length, nullable, updateable, etc.

4. Create Repository Layer

Let's create EmployeeRepository  which extends the JpaRepository  interface:

                                                            import                                                              net                                                              .javaguides                                                              .springboot                                                              .model                                                              .Employee                    ;                                          import                                                              org                                                              .springframework                                                              .data                                                              .jpa                                                              .repository                                                              .JpaRepository                    ;                                          public                                                              interface                                                              EmployeeRepository                                                              extends                                                              JpaRepository                    <                      Employee                    ,                                          Long                    > {  }                

5. Create Service Layer

EmployeeService

Let's create anEmployeeService interface with CRUD methods:

                                                            import                                        net.javaguides.springboot.model.Employee;                                          import                                        java.util.List;                                          import                                        java.util.Optional;                                          public                                                                                                                interface                                                                                                                                                                  EmployeeService                                                                                                              {                                          Employee                                                                                              saveEmployee                                                                                                                      (Employee employee)                                                                  ;                                          List<Employee>                                                                                              getAllEmployees                                                                                                                      ()                                                                  ;                                          Optional<Employee>                                                                                              getEmployeeById                                                                                                                      (                                                                                                                                    long                                                                                                                                                            id)                                                                  ;                                          Employee                                                                                              updateEmployee                                                                                                                      (Employee updatedEmployee)                                                                  ;                                                                                            void                                                                                                                                                                  deleteEmployee                                                                                                                      (                                                                                                                                    long                                                                                                                                                            id)                                                                  ; }                

EmployeeServiceImpl

Permit's create anEmployeeServiceImpl class that implements theEmployeeService interface:

                                                            import                                        cyberspace.javaguides.springboot.exception.ResourceNotFoundException;                                          import                                        net.javaguides.springboot.model.Employee;                                          import                                        cyberspace.javaguides.springboot.repository.EmployeeRepository;                                          import                                        net.javaguides.springboot.service.EmployeeService;                                          import                                        org.springframework.beans.factory.notation.Autowired;                                          import                                        org.springframework.stereotype.Service;                                          import                                        java.util.List;                                          import                                        java.util.Optional;                                          @Service                                                              public                                                                                                                class                                                                                                                                                                  EmployeeServiceImpl                                                                                                                                                                  implements                                                                                                                                                                  EmployeeService                                                                                                              {                                          individual                                        EmployeeRepository employeeRepository;                                                                                            public                                                                                                                                                                  EmployeeServiceImpl                                                                                                                      (EmployeeRepository employeeRepository)                                                                                                              {                                          this                    .employeeRepository = employeeRepository;     }                                          @Override                                                                                                                public                                                                                            Employee                                                                                              saveEmployee                                                                                                                      (Employee employee)                                                                                                              {          Optional<Employee> savedEmployee = employeeRepository.findByEmail(employee.getEmail());                                          if                    (savedEmployee.isPresent()){                                          throw                                                              new                                        ResourceNotFoundException(                      "Employee already exist with given e-mail:"                                        + employee.getEmail());         }                                          return                                        employeeRepository.salvage(employee);     }                                          @Override                                                                                                                public                                                                                            Listing<Employee>                                                                                              getAllEmployees                                                                                                                      ()                                                                                                              {                                          return                                        employeeRepository.findAll();     }                                          @Override                                                                                                                public                                                                                            Optional<Employee>                                                                                              getEmployeeById                                                                                                                      (                                                                                                                                    long                                                                                                                                                            id)                                                                                                              {                                          render                                        employeeRepository.findById(id);     }                                          @Override                                                                                                                public                                                                                            Employee                                                                                              updateEmployee                                                                                                                      (Employee updatedEmployee)                                                                                                              {                                          return                                        employeeRepository.save(updatedEmployee);     }                                          @Override                                                                                                                public                                                                                                                                                                  void                                                                                                                                                                  deleteEmployee                                                                                                                      (                                                                                                                                    long                                                                                                                                                            id)                                                                                                              {         employeeRepository.deleteById(id);     } }                

6. Unit Testing Service Layer using JUnit 5 and Mockito

Let united states of america beginning writing unit tests for EmployeeService. We should exist able to write unit tests for EmployeeService WITHOUT using any Spring features.

We are going to create a mock of EmployeeRepository using @Mock and create an EmployeeServiceImpl instance using the mock EmployeeRepository instance.

            import net.javaguides.springboot.exception.ResourceNotFoundException; import net.javaguides.springboot.model.Employee; import net.javaguides.springboot.repository.EmployeeRepository; import net.javaguides.springboot.service.impl.EmployeeServiceImpl; import static org.assertj.core.api.Assertions.assertThat; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith;  import static org.mockito.ArgumentMatchers.whatsoever; import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.willDoNothing; import static org.mockito.Mockito.*;  import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension;  import java.util.Collections; import coffee.util.List; import java.util.Optional;  @ExtendWith(MockitoExtension.class) public class EmployeeServiceTests {      @Mock     private EmployeeRepository employeeRepository;      @InjectMocks     private EmployeeServiceImpl employeeService;      individual Employee employee;      @BeforeEach     public void setup(){         //employeeRepository = Mockito.mock(EmployeeRepository.class);         //employeeService = new EmployeeServiceImpl(employeeRepository);         employee = Employee.builder()                 .id(1L)                 .firstName("Ramesh")                 .lastName("Fadatare")                 .email("ramesh@gmail.com")                 .build();     }      // JUnit examination for saveEmployee method     @DisplayName("JUnit test for saveEmployee method")     @Test     public void givenEmployeeObject_whenSaveEmployee_thenReturnEmployeeObject(){         // given - precondition or setup         given(employeeRepository.findByEmail(employee.getEmail()))                 .willReturn(Optional.empty());          given(employeeRepository.salvage(employee)).willReturn(employee);          Organisation.out.println(employeeRepository);         System.out.println(employeeService);          // when -  activeness or the behaviour that we are going test         Employee savedEmployee = employeeService.saveEmployee(employee);          System.out.println(savedEmployee);         // and then - verify the output         assertThat(savedEmployee).isNotNull();     }      // JUnit test for saveEmployee method     @DisplayName("JUnit test for saveEmployee method which throws exception")     @Exam     public void givenExistingEmail_whenSaveEmployee_thenThrowsException(){         // given - precondition or setup         given(employeeRepository.findByEmail(employee.getEmail()))                 .willReturn(Optional.of(employee));          System.out.println(employeeRepository);         Organization.out.println(employeeService);          // when -  activity or the behaviour that we are going test         org.junit.jupiter.api.Assertions.assertThrows(ResourceNotFoundException.grade, () -> {             employeeService.saveEmployee(employee);         });          // and so         verify(employeeRepository, never()).save(any(Employee.class));     }      // JUnit test for getAllEmployees method     @DisplayName("JUnit exam for getAllEmployees method")     @Test     public void givenEmployeesList_whenGetAllEmployees_thenReturnEmployeesList(){         // given - precondition or setup          Employee employee1 = Employee.builder()                 .id(2L)                 .firstName("Tony")                 .lastName("Stark")                 .email("tony@gmail.com")                 .build();          given(employeeRepository.findAll()).willReturn(List.of(employee,employee1));          // when -  action or the behaviour that we are going examination         List<Employee> employeeList = employeeService.getAllEmployees();          // so - verify the output         assertThat(employeeList).isNotNull();         assertThat(employeeList.size()).isEqualTo(2);     }      // JUnit exam for getAllEmployees method     @DisplayName("JUnit test for getAllEmployees method (negative scenario)")     @Test     public void givenEmptyEmployeesList_whenGetAllEmployees_thenReturnEmptyEmployeesList(){         // given - precondition or setup          Employee employee1 = Employee.builder()                 .id(2L)                 .firstName("Tony")                 .lastName("Stark")                 .e-mail("tony@gmail.com")                 .build();          given(employeeRepository.findAll()).willReturn(Collections.emptyList());          // when -  activity or the behaviour that we are going examination         List<Employee> employeeList = employeeService.getAllEmployees();          // then - verify the output         assertThat(employeeList).isEmpty();         assertThat(employeeList.size()).isEqualTo(0);     }      // JUnit examination for getEmployeeById method     @DisplayName("JUnit test for getEmployeeById method")     @Test     public void givenEmployeeId_whenGetEmployeeById_thenReturnEmployeeObject(){         // given         given(employeeRepository.findById(1L)).willReturn(Optional.of(employee));          // when         Employee savedEmployee = employeeService.getEmployeeById(employee.getId()).get();          // then         assertThat(savedEmployee).isNotNull();      }      // JUnit examination for updateEmployee method     @DisplayName("JUnit test for updateEmployee method")     @Test     public void givenEmployeeObject_whenUpdateEmployee_thenReturnUpdatedEmployee(){         // given - precondition or setup         given(employeeRepository.save(employee)).willReturn(employee);         employee.setEmail("ram@gmail.com");         employee.setFirstName("Ram");         // when -  activeness or the behaviour that we are going exam         Employee updatedEmployee = employeeService.updateEmployee(employee);          // and so - verify the output         assertThat(updatedEmployee.getEmail()).isEqualTo("ram@gmail.com");         assertThat(updatedEmployee.getFirstName()).isEqualTo("Ram");     }      // JUnit test for deleteEmployee method     @DisplayName("JUnit examination for deleteEmployee method")     @Test     public void givenEmployeeId_whenDeleteEmployee_thenNothing(){         // given - precondition or setup         long employeeId = 1L;          willDoNothing().given(employeeRepository).deleteById(employeeId);          // when -  activity or the behaviour that we are going test         employeeService.deleteEmployee(employeeId);          // then - verify the output         verify(employeeRepository, times(1)).deleteById(employeeId);     } }                                                              

Notice that we are using the assertThat() method to assert the conditions using the AssertJ library.

Mockito @Mock annotation is useful when we want to use the mocked object at multiple places.


When nosotros want to inject a mocked object into some other mocked object, nosotros can use @InjectMocks notation. @InjectMock creates the mock object of the class and injects the mocks that are marked with the annotations @Mock into information technology.

JUnit test for saveEmployee method:

                                  // JUnit test for saveEmployee method     @DisplayName("JUnit examination for saveEmployee method")     @Exam     public void givenEmployeeObject_whenSaveEmployee_thenReturnEmployeeObject(){         // given - precondition or setup         given(employeeRepository.findByEmail(employee.getEmail()))                 .willReturn(Optional.empty());          given(employeeRepository.save(employee)).willReturn(employee);          System.out.println(employeeRepository);         System.out.println(employeeService);          // when -  activeness or the behaviour that we are going test         Employee savedEmployee = employeeService.saveEmployee(employee);          System.out.println(savedEmployee);         // then - verify the output         assertThat(savedEmployee).isNotNull();     }              

JUnit test for saveEmployee method which throws Exception:

                                  // JUnit test for saveEmployee method     @DisplayName("JUnit examination for saveEmployee method which throws exception")     @Exam     public void givenExistingEmail_whenSaveEmployee_thenThrowsException(){         // given - precondition or setup         given(employeeRepository.findByEmail(employee.getEmail()))                 .willReturn(Optional.of(employee));          Organization.out.println(employeeRepository);         System.out.println(employeeService);          // when -  action or the behaviour that we are going examination         org.junit.jupiter.api.Assertions.assertThrows(ResourceNotFoundException.class, () -> {             employeeService.saveEmployee(employee);         });          // then         verify(employeeRepository, never()).save(any(Employee.form));     }              

JUnit test for getAllEmployees method:

                                  @DisplayName("JUnit test for getAllEmployees method")     @Examination     public void givenEmployeesList_whenGetAllEmployees_thenReturnEmployeesList(){         // given - precondition or setup          Employee employee1 = Employee.builder()                 .id(2L)                 .firstName("Tony")                 .lastName("Stark")                 .email("tony@gmail.com")                 .build();          given(employeeRepository.findAll()).willReturn(List.of(employee,employee1));          // when -  activeness or the behaviour that we are going examination         List<Employee> employeeList = employeeService.getAllEmployees();          // and then - verify the output         assertThat(employeeList).isNotNull();         assertThat(employeeList.size()).isEqualTo(2);     }              

JUnit examination for getEmployeeById method

                                  // JUnit test for getEmployeeById method     @DisplayName("JUnit test for getEmployeeById method")     @Test     public void givenEmployeeId_whenGetEmployeeById_thenReturnEmployeeObject(){         // given         given(employeeRepository.findById(1L)).willReturn(Optional.of(employee));          // when         Employee savedEmployee = employeeService.getEmployeeById(employee.getId()).get();          // so         assertThat(savedEmployee).isNotNull();      }              

JUnit examination for updateEmployee method:

                                  // JUnit test for updateEmployee method     @DisplayName("JUnit test for updateEmployee method")     @Examination     public void givenEmployeeObject_whenUpdateEmployee_thenReturnUpdatedEmployee(){         // given - precondition or setup         given(employeeRepository.relieve(employee)).willReturn(employee);         employee.setEmail("ram@gmail.com");         employee.setFirstName("Ram");         // when -  action or the behaviour that nosotros are going test         Employee updatedEmployee = employeeService.updateEmployee(employee);          // and then - verify the output         assertThat(updatedEmployee.getEmail()).isEqualTo("ram@gmail.com");         assertThat(updatedEmployee.getFirstName()).isEqualTo("Ram");     }              

JUnit test for deleteEmployee method

                                  // JUnit test for deleteEmployee method     @DisplayName("JUnit exam for deleteEmployee method")     @Exam     public void givenEmployeeId_whenDeleteEmployee_thenNothing(){         // given - precondition or setup         long employeeId = 1L;          willDoNothing().given(employeeRepository).deleteById(employeeId);          // when -  action or the behaviour that we are going test         employeeService.deleteEmployee(employeeId);          // then - verify the output         verify(employeeRepository, times(1)).deleteById(employeeId);     }              

7. Demo - Run JUnit Tests


Free Leap Boot Tutorial | Full In-depth Course | Learn Spring Boot in x Hours


Lookout this course on YouTube at Spring Kicking Tutorial | Fee 10 Hours Full Course

How To Unittest Spring Boot Service Layer,

Source: https://www.javaguides.net/2022/03/spring-boot-unit-testing-service-layer.html

Posted by: meadowshopper.blogspot.com

0 Response to "How To Unittest Spring Boot Service Layer"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel