15_Springboot异常处理机制及junit的支持

文章目录

  • Spring Boot异常处理机制及对Junit的支持
    • 0x01_异常处理机制
      • 错误页面的修改
      • 利用SpringMVC异常
    • 0x02_对junit的支持
      • 单元测试
      • 功能测试
      • 切片测试

Spring Boot异常处理机制及对Junit的支持

0x01_异常处理机制

错误页面的修改

默认情况,Spring Boot项目错误页面是Whitelable Error Page。当项目实际上线,如果给用户显示这个页面就不是很友好。当系统出现异常时应该给用户显示更加友好的错误页面。

  • 1.设置具体的状态码页面

在templates/下新建error文件夹,在error中新建:状态码.html的页面。例如当出现500时显示的页面为500.html

  • 2.使用x进行模糊匹配

当出现5开头状态码的错误时,显示页面可以命名为5xx.html

当出现50开头状态码的错误时,显示页面可以命名为50x.html

  • 3.统一错误显示页面

在templates下新建error.html。如果项目中不存在具体状态码的页面或没有使用x成功匹配的页面时,显示error.html作为错误显示页面。

如果没有模版引擎目录,没有模板引擎(模板引擎找不到这个错误页面),默认静态资源文件夹下找;以上都没有错误页面,就是默认来到SpringBoot默认的错误提示页面

上面的比较简单,不再做测试。

利用SpringMVC异常

这个之前分析过,可以参考下面的文章:Spring MVC异常。

0x02_对junit的支持

如果是用IDEA的initializer创建的Spring boot项目,在spring-boot-starter-test起步依赖中就有junit的支持:

15_Springboot异常处理机制及junit的支持_第1张图片

可以看到Spring boot对于junit5的支持。

在测试包的测试类中,@SpringBootTest替代了spring-test中的@ContextConfiguration注解,目的是加载ApplicationContext,启动spring容器。

使用@SpringBootTest时并没有像@ContextConfiguration一样显示指定locations或classes属性,原因在于@SpringBootTest注解会自动检索程序的配置文件,检索顺序是从当前包开始,逐级向上查找被@SpringBootApplication@SpringBootConfiguration注解的类。

15_Springboot异常处理机制及junit的支持_第2张图片

Spring Test与JUnit等其他测试框架结合起来,提供了便捷高效的测试手段。而Spring Boot Test 是在Spring Test之上的再次封装,增加了切片测试,增强了mock能力。

整体上,Spring Boot Test支持的测试种类,大致可以分为如下三类:

  • 单元测试:一般面向方法,编写一般业务代码时,测试成本较大。涉及到的注解有@Test
  • 切片测试:一般面向难于测试的边界功能,介于单元测试和功能测试之间。涉及到的注解有@RunWith @WebMvcTest等。
  • 功能测试:一般面向某个完整的业务功能,同时也可以使用切面测试中的mock能力,推荐使用。涉及到的注解有@RunWith @SpringBootTest等。

功能测试过程中的几个关键要素及支撑方式如下:

  • 测试运行环境:通过@RunWith@SpringBootTest启动spring容器。
  • mock能力:Mockito提供了强大mock功能。
  • 断言能力:AssertJHamcrestJsonPath提供了强大的断言能力。

一旦依赖了spring-boot-starter-test,下面这些类库将被一同依赖进去:

  • JUnit:java测试事实上的标准,默认依赖版本是4.12(JUnit5和JUnit4差别比较大,集成方式有不同)。
  • Spring Test & Spring Boot Test:Spring的测试支持。
  • AssertJ:提供了流式的断言方式。
  • Hamcrest:提供了丰富的matcher。
  • Mockito:mock框架,可以按类型创建mock对象,可以根据方法参数指定特定的响应,也支持对于mock调用过程的断言。
  • JSONassert:为JSON提供了断言功能。
  • JsonPath:为JSON提供了XPATH功能。
15_Springboot异常处理机制及junit的支持_第3张图片

@RunWith是Junit4提供的注解,将Spring和Junit链接了起来。假如使用Junit5,不再需要使用@ExtendWith注解,@SpringBootTest和其它@*Test默认已经包含了该注解。

单元测试

在test包下的测试类中,提供了测试的方法:

package com.bones;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class SpringbootjunitApplicationTests {

    @Test
    void contextLoads() {
    }

}

功能测试

一般情况下,使用@SpringBootTest后,Spring将加载所有被管理的bean,基本等同于启动了整个服务,此时便可以开始功能测试。

由于web服务是最常见的服务,且我们对于web服务的测试有一些特殊的期望,所以@SpringBootTest注解中,给出了webEnvironment参数指定了web的environment,该参数的值一共有四个可选值:

  • MOCK:此值为默认值,该类型提供一个mock环境,可以和@AutoConfigureMockMvc@AutoConfigureWebTestClient搭配使用,开启Mock相关的功能。注意此时内嵌的服务(servlet容器)并没有真正启动,也不会监听web服务端口。
  • RANDOM_PORT:启动一个真实的web服务,监听一个随机端口。
  • DEFINED_PORT:启动一个真实的web服务,监听一个定义好的端口(从application.properties读取)。
  • NONE:启动一个非web的ApplicationContext,既不提供mock环境,也不提供真实的web服务。

注:如果当前服务的classpath中没有包含web相关的依赖,spring将启动一个非web的ApplicationContext,此时的webEnvironment就没有什么意义了

切片测试

所谓切片测试,官网文档称为 “slice” of your application,实际上是对一些特定组件的称呼。这里的slice并非单独的类(毕竟普通类只需要基于JUnit的单元测试即可),而是介于单元测试和集成测试中间的范围。

slice是指一些在特定环境下才能执行的模块,比如MVC中的Controller、JDBC数据库访问、Redis客户端等,这些模块大多脱离特定环境后不能独立运行,假如spring没有为此提供测试支持,开发者只能启动完整服务对这些模块进行测试,这在一些复杂的系统中非常不方便,所以spring为这些模块提供了测试支持,使开发者有能力单独对这些模块进行测试。

通过@*Test开启具体模块的测试支持,开启后spring仅加载相关的bean,无关内容不会被加载。

使用@WebMvcTest用来校验controllers是否正常工作的示例:

随便准备一个最简单的controller处理单元:

package com.bones.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

    @RequestMapping("/test")
    public String test(){
        System.out.println("==================testController=================");
        return "test";
    }
}

测试:

//@SpringBootTest
@WebMvcTest(TestController.class)
class SpringbootjunitApplicationTests {
    @Autowired
    MockMvc mvc;

    @Test
    void testCon() {
        try {
            ResultActions perform = mvc.perform(MockMvcRequestBuilders.get("/test"));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

上面的测试没有启动容器,使用@WebMvcTestMockMvc搭配使用,对Controller进行测试(注意:仅仅只是对controller进行简单的测试,如果Controller中依赖用@Autowired注入的service、dao等则不能这样测试)。

你可能感兴趣的:(Spring,Boot,junit,spring,boot,spring)