SpringBoot——学会使用Test,检测自己写的代码(一)

简介: SpringBoot——学会使用Test,检测自己写的代码(一)

一、前言

各位小伙伴们,上次已经讲解了用SpringBoot实现技术整合,体验SpringBoot的简化开发,今天这一篇介绍代码的测试。测试是保障程序正确性的唯一屏障,在企业级开发中更是不可缺少,但是由于测试代码往往不产生实际效益,所以在发开中,有时会跳过测试,我们往往这一块比较短板,所以还是要拿出来把这一块知识好好说说,做一名专业的开发人员。


本篇文章使用springboot技术,实现测试功能!


二、测试专用属性

测试过程本身并不是一个复杂的过程,但是很多情况下测试时需要模拟一些线上情况,或者模拟一些特殊情况。如果当前环境按照线上环境已经设定好了,例如是下面的配置:


person:
  name: "tom"
  age: 18


但是你现在想测试对应的兼容性,需要测试如下配置:


person:
  name: "cat"
  age: 20


这个时候我们不能每次测试的时候都去修改源码application.yml中的配置进行测试呢?每次测试前改过来,每次测试后改回去,这太麻烦了。于是我们就想,需要在测试环境中创建一组临时属性,去覆盖我们源码中设定的属性,这样测试用例就相当于是一个独立的环境,能够独立测试,这样就方便多了。下面就来介绍该如何解决这个问题:


1、临时属性

假如我有一个application.yml文件,配置是这样的:


test:
  prop: testValue1


当我准备测试的时候,在不修改源码的情况下,想改变prop属性为testValue2,该怎么办呢?


在测试用例程序中,可以通过对注解@SpringBootTest添加属性来模拟临时属性,具体如下:


@Slf4j
@SpringBootTest(properties = {"test.prop=testValue2"})
class PropertiesAndArgsTest {
    @Value("${test.prop}")
    private String msg;
    @Test
    void test01() {
        log.info(msg);
    }
}


看一看运行结果:

image.png

使用注解@SpringBootTest的properties属性就可以为当前测试用例添加临时的属性,覆盖源码配置文件中对应的属性值进行测试。


2、临时参数

除了上述这种情况,在使用命令行启动springboot程序时,通过命令行参数也可以设置属性值。而且线上启动程序时,通常都会添加一些专用的配置信息。作为开发者提供了对应的书写内容后,能否提前测试一下这些配置信息是否有效呢?当时是可以的,还是通过注解@SpringBootTest的另一个属性来进行设定。


@Slf4j
@SpringBootTest(properties = {"test.prop=testValue2"},args = {"--test.prop=testValue3"})
class PropertiesAndArgsTest {
    @Value("${test.prop}")
    private String msg;
    @Test
    void test01() {
        log.info(msg);
    }
}


运行结果:

image.png

使用注解@SpringBootTest的args属性就可以为当前测试用例模拟命令行参数并进行测试。


说到这里,好奇的小伙伴们可能会问,如果两者共存呢?其实如果思考一下配置属性与命令行参数的加载优先级,这个结果就不言而喻了。在属性加载的优先级设定中,有明确的优先级设定顺序,让我们打开官网:SpringBoot官网文档

image.png

在这个属性加载优先级的顺序中,明确规定了命令行参数的优先级排序是11,而配置属性的优先级是3,结果不言而喻了,args属性配置优先于properties属性配置加载。


总结:


加载测试临时属性可以通过注解@SpringBootTest的properties和args属性进行设定,此设定应用范围仅适用于当前测试用例

三、测试专用配置

如果想在测试的时候临时加载一些Bean能不做呢?也就是说我们测试时,想搞一些独立的Bean出来,专门应用于测试环境,能否实现呢?答案是当然可以,具体操作步骤如下:


步骤①:在测试包test中创建专用的测试环境配置类,是在test包中!!


@Configuration
public class MsgConfig {
    @Bean
    public String msg() {
        return "Bean Message";
    }
}


上述配置仅用于演示当前实验效果,实际开发可不能这么注入String类型的数据


步骤②:在启动测试环境时,导入测试环境专用的配置类


@Slf4j
@SpringBootTest
public class ConfigurationTest {
    @Autowired
    private String msg;
    @Test
    void test01() {
        log.info(msg);
    }
}


运行结果:

image.png

这样我们就可以实现每一个不同的测试用例加载不同的bean的效果,丰富测试用例的编写,同时不影响开发环境的配置。


四、Web环境模拟测试

实际企业开发不仅要保障业务层与数据层的功能安全有效,也要保障表现层的功能正常。但是我们目的对表现层的测试都是通过postman手工测试的,并没有在打包过程中体现表现层功能被测试通过。能否在测试用例中对表现层进行功能测试呢?答案也是可以的!


在测试中对表现层功能进行测试需要一个基础和一个功能。所谓的一个基础是运行测试程序时,必须启动web环境,不然没法测试web功能。一个功能是必须在测试程序中具备发送web请求的能力,不然无法实现web功能的测试。所以在测试用例中测试表现层接口这项工作就转换成了两件事,如何在测试类中启动web测试?如何在测试类中发送web请求?


1、测试类中启动web环境

每一个springboot的测试类上方都会标准@SpringBootTest注解,而注解带有一个属性,叫做webEnvironment。通过该属性就可以设置在测试用例中启动web环境,具体如下:


@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class WebTest {
}


测试类中启动web环境时,可以指定启动的Web环境对应的端口,springboot提供了4种设置值,分别如下:

image.png


MOCK:根据当前设置确认是否启动web环境,例如使用了Servlet的API就启动web环境,属于适配性的配置

DEFINED_PORT:使用自定义的端口作为web服务器端口

RANDOM_PORT:使用随机端口作为web服务器端口

NONE:不启动web环境

建议大家测试时使用RANDOM_PORT,避免代码中因为写死设定引发线上功能打包测试时由于端口冲突导致意外现象的出现。就是说你程序中写了用8080端口,结果线上环境8080端口被占用了,结果你代码中所有写的东西都要改,这就是写死代码的代价。现在你用随机端口就可以测试出来你有没有这种问题的隐患了。


测试环境中的web环境已经搭建好了,下面就可以来解决第二个问题了,如何在程序代码中发送web请求。


2、测试类中发送请求

先提前写一个controller,用于后面的测试,代码如图:

image.png


我们该在测试类中如何发送请求呢?具体操作如下:


步骤①:在测试类中开启web虚拟调用功能,通过注解@AutoConfigureMockMvc实现此功能的开启


@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
//日志调用
@Slf4j
//开启虚拟MVC调用
@AutoConfigureMockMvc
public class WebTest {
}


步骤②:定义发起虚拟调用的对象MockMVC,通过自动装配的形式初始化对象


@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Slf4j
@AutoConfigureMockMvc
public class WebTest {
    @Test
    void test01(@Autowired MockMvc mvc) {
    }
}


步骤③:创建一个虚拟请求对象,封装请求的路径,并使用MockMVC对象发送对应请求


@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Slf4j
@AutoConfigureMockMvc
public class WebTest {
    @Test
    void test01(@Autowired MockMvc mvc) throws Exception {
        //创建虚拟请求,当前访问/books 
            MockHttpServletRequestBuilder requestBuilder =
                     MockMvcRequestBuilders.get("/books");
  //执行对应的请求
            mvc.perform(requestBuilder);
        }
}


执行测试程序,现在就可以正常的发送/books对应的请求了,注意访问路径不要写http://localhost:8080/books,因为前面的服务器IP地址和端口使用的是当前虚拟的web环境,无需指定,仅指定请求的具体路径即可。


总结:


在测试类中测试web层接口要保障测试类启动时启动web容器,使用@SpringBootTest注解的webEnvironment属性可以虚拟web环境用于测试

为测试方法注入MockMvc对象,通过MockMvc对象可以发送虚拟请求,模拟web请求调用过程


相关文章
|
1月前
|
Java 数据安全/隐私保护 Spring
揭秘Spring Boot自定义注解的魔法:三个实用场景让你的代码更加优雅高效
揭秘Spring Boot自定义注解的魔法:三个实用场景让你的代码更加优雅高效
|
1月前
|
前端开发 IDE Java
"揭秘前端转Java的秘径:SpringBoot Web极速入门,掌握分层解耦艺术,让你的后端代码飞起来,你敢来挑战吗?"
【8月更文挑战第19天】面向前端开发者介绍Spring Boot后端开发,通过简化Spring应用搭建,快速实现Web应用。本文以创建“Hello World”应用为例,展示项目基本结构与运行方式。进而深入探讨三层架构(Controller、Service、DAO)下的分层解耦概念,通过员工信息管理示例,演示各层如何协作及依赖注入的使用,以此提升代码灵活性与可维护性。
34 2
|
1月前
|
安全 Java Shell
"SpringBoot防窥秘籍大公开!ProGuard混淆+xjar加密,让你的代码穿上隐形斗篷,黑客也无奈!"
【8月更文挑战第11天】开发SpringBoot应用时,保护代码免遭反编译至关重要。本文介绍如何运用ProGuard和xjar强化安全性。ProGuard能混淆代码,去除未使用的部分,压缩字节码,使反编译困难。需配置ProGuard规则文件并处理jar包。xjar则进一步加密jar包内容,即使被解压也无法直接读取。结合使用这两种工具可显著提高代码安全性,有效保护商业机密及知识产权。
170 3
|
1月前
|
Java API 数据格式
Spring Boot API参数读取秘籍大公开!6大神器助你秒变参数处理大师,让你的代码飞起来!
【8月更文挑战第4天】Spring Boot凭借其便捷的开发和配置特性,成为构建微服务的热门选择。高效处理HTTP请求参数至关重要。本文介绍六种核心方法:查询参数利用`@RequestParam`;路径变量采用`@PathVariable`;请求体通过`@RequestBody`自动绑定;表单数据借助`@ModelAttribute`或`@RequestParam`;请求头使用`@RequestHeader`;Cookie则依靠`@CookieValue`。每种方法针对不同场景,灵活运用可提升应用性能与用户体验。
44 9
|
23天前
|
监控 安全 Java
【开发者必备】Spring Boot中自定义注解与处理器的神奇魔力:一键解锁代码新高度!
【8月更文挑战第29天】本文介绍如何在Spring Boot中利用自定义注解与处理器增强应用功能。通过定义如`@CustomProcessor`注解并结合`BeanPostProcessor`实现特定逻辑处理,如业务逻辑封装、配置管理及元数据分析等,从而提升代码整洁度与可维护性。文章详细展示了从注解定义、处理器编写到实际应用的具体步骤,并提供了实战案例,帮助开发者更好地理解和运用这一强大特性,以实现代码的高效组织与优化。
35 0
|
23天前
|
Java 开发者 Spring
Spring Boot大法好:解耦、隔离、异步,让代码‘活’起来,性能飙升的秘密武器!
【8月更文挑战第29天】解耦、隔离与异步是Spring Boot中的关键设计原则,能大幅提升软件的可维护性、扩展性和性能。本文通过示例代码详细探讨了这些原则的应用:依赖注入和面向接口编程实现解耦;模块化设计与配置文件实现隔离;`@Async`注解和`CompletableFuture`实现异步处理。综合运用这些原则,可以显著提升软件质量和性能,使系统更加健壮、灵活和高效。
22 0
|
2月前
|
存储 Java Serverless
Java Spring Boot应用如何实现推送代码到指定仓库并自动部署
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
1月前
|
Java 测试技术
Java SpringBoot Test 单元测试中包括多线程时,没跑完就结束了
Java SpringBoot Test 单元测试中包括多线程时,没跑完就结束了
23 0
|
2月前
|
物联网
好的资源链接,gitee全糖咖啡,B站视频转成mp4,全糖咖啡 / 物联网网关数据上传,,全糖咖啡 / springboot+百度智能车牌检测
好的资源链接,gitee全糖咖啡,B站视频转成mp4,全糖咖啡 / 物联网网关数据上传,,全糖咖啡 / springboot+百度智能车牌检测
|
2月前
|
存储 Java
软件开发常用之SpringBoot文件上传接口编写(中),一本书,代码大全(里面有很多代码重构的方法),屎山代码的原因是不断追加逻辑,在错误代码上堆积新的功能,在写完逻辑之后去思考一下,逻辑合理不
软件开发常用之SpringBoot文件上传接口编写(中),一本书,代码大全(里面有很多代码重构的方法),屎山代码的原因是不断追加逻辑,在错误代码上堆积新的功能,在写完逻辑之后去思考一下,逻辑合理不