📜  使用 Mockito 和 Junit 在 Spring Boot 项目中进行单元测试

📅  最后修改于: 2022-05-13 01:54:54.281000             🧑  作者: Mango

使用 Mockito 和 Junit 在 Spring Boot 项目中进行单元测试

Spring Boot 建立在 Spring 之上,包含了 Spring 的所有特性。并且由于其快速的生产就绪环境使开发人员能够直接专注于逻辑而不是为配置和设置而苦苦挣扎,如今它正成为开发人员的最爱。 Spring Boot 是一个基于微服务的框架,在其中制作可用于生产的应用程序只需要很少的时间。以下是 Spring Boot 的一些特性:

  • 它允许避免在 spring 中存在的 XML 的繁重配置
  • 它提供易于维护和创建 REST 端点
  • 它包括嵌入式 Tomcat 服务器
  • 部署非常简单,war和jar文件可以轻松部署在tomcat服务器中

Mockito是一个开源测试框架,用于对Java应用程序进行单元测试。它在开发可测试的应用程序中起着至关重要的作用。 Mockito 用于模拟接口,以便可以将虚拟功能添加到可用于单元测试的模拟接口中。单元测试是一种软件测试,其中测试软件的各个组件。使用 Mockito 框架的主要目标是通过模拟外部依赖项并在测试代码中使用它们来简化测试的开发。因此,Mockito 提供了更简单的测试代码,更易于理解、可读性和可修改性。 Mockito 还可以与JUnitTestNG等其他测试框架一起使用。 JUnit框架是一个Java框架,也用于测试。现在,当需要在Java中执行测试时,JUnit 被用作标准。所以在本文中,我们将使用 Mockito 和 Junit 在 Spring Boot 项目中执行单元测试。

分步实施

第一步:参考这篇文章如何使用 IntelliJ IDEA 创建 Spring Boot 项目并创建一个 Spring Boot 项目。

步骤 2:添加以下依赖项,如下所示:

  • 春季网络
  • MySQL 数据库
  • 龙目岛
  • 春季数据 JPA

示例: pom.xml 文件

XML


    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.5.4
         
    
    com.demo
    BootDemoApp
    0.0.1-SNAPSHOT
    BootDemoApp
    BootDemoApp
    
        16
    
    
        
            org.springframework.boot
            spring-boot-starter-web
        
 
        
            org.springframework.boot
            spring-boot-starter-data-jpa
        
 
        
            mysql
            mysql-connector-java
            runtime
        
 
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
 
        
            org.projectlombok
            lombok
            true
        
 
 
    
 
    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    
 


Java
package com.demo.entites;
 
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
 
import javax.persistence.Entity;
import javax.persistence.Id;
 
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
 
// Class
public class Person {
    @Id
    private Integer personId;
    private String personName;
    private String personCity;
}


Java
package com.demo.repo;
 
import com.demo.entites.Person;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
 
// Interface
// Extends JpaRepository
public interface PersonRepo
    extends JpaRepository {
    @Query(
        "SELECT CASE WHEN COUNT(s) > 0 THEN TRUE ELSE FALSE END FROM Person s WHERE s.personId = ?1")
    Boolean
    isPersonExitsById(Integer id);
}


Java
package com.demo.services;
 
import com.demo.entites.Person;
import com.demo.repo.PersonRepo;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
// Annotation
@Service
 
// Class
public class PersonService {
 
    @Autowired private PersonRepo repo;
 
    public List getAllPerson()
    {
        return this.repo.findAll();
    }
 
    public PersonService(PersonRepo repo)
    {
        // this keyword refers to current instance
        this.repo = repo;
    }
}


Java
package com.demo.controllers;
 
import com.demo.services.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
public class PersonController {
 
    @Autowired
    private PersonService personService;
 
    @GetMapping("/persons")
    public ResponseEntity getAllPersons() {
        return ResponseEntity.ok(this.personService.getAllPerson());
    }
}


Java
package com.demo.repo;
 
import com.demo.entites.Person;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
 
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
 
@SpringBootTest
class PersonRepoTest {
 
    @Autowired
    private PersonRepo personRepo;
 
    @Test
    void isPersonExitsById() {
        Person person = new Person(1001, "Amiya", "Bhubaneswar");
        personRepo.save(person);
        Boolean actualResult = personRepo.isPersonExitsById(1001);
        assertThat(actualResult).isTrue();
    }
}


Java
// Java Program to Illustrate Unit Testing of Service Class
 
package com.demo.services;
 
import static org.mockito.Mockito.verify;
 
import com.demo.repo.PersonRepo;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
 
@ExtendWith(MockitoExtension.class)
 
// Main class
class PersonServiceTest {
 
    @Mock private PersonRepo personRepo;
 
    private PersonService personService;
 
    @BeforeEach void setUp()
    {
        this.personService
            = new PersonService(this.personRepo);
    }
 
    @Test void getAllPerson()
    {
        personService.getAllPerson();
        verify(personRepo).findAll();
    }
}


第 3 步:创建包和文件,如下图所示。以下是该项目的完整文件结构。

第 4 步:在实体包内

它是通过在 Person 中创建一个简单的 POJO 类来完成的。 Java文件。

Java

package com.demo.entites;
 
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
 
import javax.persistence.Entity;
import javax.persistence.Id;
 
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
 
// Class
public class Person {
    @Id
    private Integer personId;
    private String personName;
    private String personCity;
}

第 5 步:在存储库包中

创建一个简单的接口并将接口命名为 PersonRepo。该接口将扩展JpaRepository。

Java

package com.demo.repo;
 
import com.demo.entites.Person;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
 
// Interface
// Extends JpaRepository
public interface PersonRepo
    extends JpaRepository {
    @Query(
        "SELECT CASE WHEN COUNT(s) > 0 THEN TRUE ELSE FALSE END FROM Person s WHERE s.personId = ?1")
    Boolean
    isPersonExitsById(Integer id);
}

第 6 步:在服务包内

在包内创建一个名为PersonService的类。

Java

package com.demo.services;
 
import com.demo.entites.Person;
import com.demo.repo.PersonRepo;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
// Annotation
@Service
 
// Class
public class PersonService {
 
    @Autowired private PersonRepo repo;
 
    public List getAllPerson()
    {
        return this.repo.findAll();
    }
 
    public PersonService(PersonRepo repo)
    {
        // this keyword refers to current instance
        this.repo = repo;
    }
}

第 7 步:在控制器包内

在包中创建一个名为PersonController 的类。

Java

package com.demo.controllers;
 
import com.demo.services.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
public class PersonController {
 
    @Autowired
    private PersonService personService;
 
    @GetMapping("/persons")
    public ResponseEntity getAllPersons() {
        return ResponseEntity.ok(this.personService.getAllPerson());
    }
}

第 8 步:下面是 application.properties 文件的代码

server.port=8082

# Configuration for MySQL Database
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://localhost:3306/schooldb
spring.datasource.username=amiya559
spring.datasource.password=password.123
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.show-sql:true

现在您的示例 Spring Boot 项目已准备就绪,我们将在此示例项目中执行单元测试。

第 9 步:创建以下包和类,如下图所示。 (绿色框内)

第 10 步:存储库类的单元测试

在 test > repo 包中创建一个名为PersonRepoTest的类。

Java

package com.demo.repo;
 
import com.demo.entites.Person;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
 
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
 
@SpringBootTest
class PersonRepoTest {
 
    @Autowired
    private PersonRepo personRepo;
 
    @Test
    void isPersonExitsById() {
        Person person = new Person(1001, "Amiya", "Bhubaneswar");
        personRepo.save(person);
        Boolean actualResult = personRepo.isPersonExitsById(1001);
        assertThat(actualResult).isTrue();
    }
}

第 11 步:服务类的单元测试

在 test > services 包中创建一个名为PersonServiceTest的类。

Java

// Java Program to Illustrate Unit Testing of Service Class
 
package com.demo.services;
 
import static org.mockito.Mockito.verify;
 
import com.demo.repo.PersonRepo;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
 
@ExtendWith(MockitoExtension.class)
 
// Main class
class PersonServiceTest {
 
    @Mock private PersonRepo personRepo;
 
    private PersonService personService;
 
    @BeforeEach void setUp()
    {
        this.personService
            = new PersonService(this.personRepo);
    }
 
    @Test void getAllPerson()
    {
        personService.getAllPerson();
        verify(personRepo).findAll();
    }
}

同样,我们可以对您的 Spring Boot 项目的不同单元进行测试。