使用Spring Boot进行单元测试的入门教程

157 阅读5分钟

使用Spring Boot进行单元测试的入门教程

编写像样的单元测试是一项需要很长时间才能完善的技能。单元测试是开发人员确保单个单元或组件正常工作的方法之一。

在部署任何代码之前,都要进行单元测试以满足质量标准。单元测试确保Spring Boot应用程序及其组件按预期工作。

前提条件

对于本教程,读者将需要。

  • Java编程的基本知识
  • 有关Spring Boot的基本知识
  • 安装了一个IDE。在本教程中,我们将使用IntelliJ IDEA Ultimate

开始吧

在开始单元测试之前,让我们首先了解为什么单元测试很重要。

单元测试的优势

  • 单元测试使开发人员能够更早地定位和修复错误。

  • 它促进了高质量的代码。通过多次运行测试,开发人员在修改代码时获得信心。

  • 单元测试可以提高一个人的编码技能。通过这个过程,开发人员可以学习如何编写更好的代码。

单元测试的最佳实践

以下是编写单元测试时的一些最佳实践。

把需要评估的功能分开。

要测试的功能应该通过限制加载组件的使用环境来隔离。这可以通过使用@Test 注解来实现。

这种方法的优点是容易定位棘手的bug,从而促进清洁生产。

这个特殊的功能,如果明智地使用,可以帮助开发人员测试大型应用程序,而不会对性能产生负面影响。

分片加载功能

将应用程序的上下文限制在测试场景中所包含的Spring组件是至关重要的。这可以通过在注解声明中包括它们来实现。

使用@DataJpaTest 注释

为了提高不同组件的性能,我们使用@DataJpaTest 注释。

这是因为它不会加载beans 注释的@Service@Controller ,以及整个应用程序上下文。

执行与数据库相关的测试

模拟与数据库相关的Bean,并为执行测试的Spring profile禁用Spring Boot测试DB的初始化是很好的。

在测试控制器时,你应该始终牢记这一做法。

使你的测试简单化

每当高级开发人员向初学者传授单元测试时,他们应始终确保测试是简单明了的。

为了达到这个目的,开发人员应该保持测试的低循环复杂性。循环复杂性是一种编码统计,显示一个程序可以采取多少种不同的执行路径。

开发人员在处理复杂性较低的代码时,不太可能引入问题,因为它更容易理解和维护。

测试的原因

存储库

存储库是应用程序和数据库之间的桥梁。它被测试以确保数据库和应用程序之间的关系被正确地实现。

服务

这是实现业务逻辑的层。它被测试以确保业务逻辑是正确的。

如何测试控制器

现在让我们来看看如何在Spring Boot中测试控制器。为了实现这一目标,你需要使用Spring InitializerIntelliJ IDEA Ultimate导入一些依赖项。

IntelliJ IDEA Ultimate中,让我们使用Spring Initializr服务创建一个Spring Boot应用程序。

打开file>new>project ,选择Spring Initializr,如下图所示。

注意:如果你没有使用IntelliJ IDEA Ultimate,你需要进入Spring Initializer,并将Spring Web依赖性添加到你的项目中。生成压缩文件,然后用你喜欢的IDE打开它。

Spring Initializer

注意:我已经把我的包的名字重命名为unittesting

点击下一步继续。在搜索栏中输入web来搜索所需的依赖项。选择Spring Web,然后点击完成,下载initializr模板。

Spring Initializer

我们已经成功准备了环境。🔥现在我们需要测试控制器。在/src/main/java/unittesting ,创建一个名为controller 的新包。

继续在/src/main/java/unittesting/controller ,创建一个名为HelloContoller.java 的Java类。在该文件中,添加下面的代码。

package unittesting.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello(@RequestParam(name = "name", defaultValue = "Hello world") String name){
        return name;
    }
}

让我们看一下上面的代码片段。

  • @GetMapping 是一个注解,用于将请求映射到方法上。
  • @RequestParam 是一个注解,用于将请求参数映射到方法参数。
  • @RestController 是一个注解,用来表示该类是一个控制器。

下一步是生成控制器测试。在HelloController.java 文件中,右击并在菜单中选择Generate..>Test..

选择成员下的可用方法(我们要测试的),然后点击确定

Spring Initializer

一个新的文件/src/test/java/unittesting/controller/HelloControllerTest.java 将被创建。修改该文件,使其具有下面的代码。

package unittesting.controller;
import org.junit.jupiter.api.Test;
// import all the static methods from the Assertions class, so we may use them in this class
import static org.junit.jupiter.api.Assertions.*;

class HelloControllerTest {
    @Test
    void hello() {
        HelloController controller = new HelloController(); // instance of the controller
        String response = controller.hello("Hello world"); // act
        assertEquals("Hello world", response); // assert
    }
}

到目前为止,我们已经创建了一个不包括Spring上下文的测试。我们现在应该使用JUnit 5扩展生成另一个测试。它将有Spring提供的Spring扩展。

重复同样的程序来生成另一个测试。将第二个测试类命名为HelloControllerIntTest.java 。在/src/test/java/controller/HelloControllerIntTest.java ,修改代码,如下所示。

package unittesting.controller;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
@ExtendWith({SpringExtension.class})
@WebMvcTest(HelloController.class)
class HelloControllerIntTest {
    @Autowired
    private MockMvc mvc;
    @Test
    void hello() throws Exception {
        RequestBuilder request = MockMvcRequestBuilders.get("/hello");
        MvcResult result = mvc.perform(request).andReturn();
        assertEquals("Hello world", result.getResponse().getContentAsString());
    }
}

在上面的代码片段中。

  • @ExtendWith 是一个注解,用于用SpringExtension扩展测试。
  • @WebMvcTest 自动配置MockMVC(所以我们可以像上面的代码中演示的那样自动连接它)。我们指定我们要测试的类。

让我们测试一下控制器,确保它能正常工作。

HelloControllerTest.java 文件中,右键单击并运行HelloControllerTest 。你应该看到测试通过,如下图所示。

Test output

结论

恭喜你!你已经成功地测试了控制器。你已经成功测试了控制器。在Spring Boot中,有多种方法可以创建单元测试。在本教程中,我们已经学会了如何使用MockMV进行测试。