springboot集成junit编写单元测试实战

目录
  • 一:查看jar包版本号是否为junit4;
  • 二:实战应用:
  • 三:扩展

在做单元测试时,代码覆盖率常常被拿来作为衡量测试好坏的指标,甚至,用代码覆盖率来考核测试任务完成情况,比如,代码覆盖率必须达到80%或 90%。于是乎,测试人员费尽心思设计案例覆盖代码。用代码覆盖率来衡量,有利也有弊。

首先,让我们先来了解一下所谓的“代码覆盖率”。我找来了所谓的定义:代码覆盖率 = 代码的覆盖程度,一种度量方式。

一:查看jar包版本号是否为junit4;

junit自身注解:

@BeforeClass 全局只会执行一次,而且是第一个运行
@Before 在测试方法运行之前运行
@Test 测试方法
@After 在测试方法运行之后允许
@AfterClass 全局只会执行一次,而且是最后一个运行
@Ignore 忽略此方法

坑:为什么要先看版本号因为在junit5中@Before无效需要使用@BeforeEach;

二:实战应用:

idea快捷创建测试类:

1.首先要保证有test类,和main同级:

2.创建

编辑

添加图片注释,不超过 140 字(可选)

3.编写单元测试

@RunWith(SpringRunner.class):运行器指定
@SpringBootTest(classes =IotSystemApplication.class, webEnvironment =SpringBootTest.WebEnvironment.DEFINED_PORT)
@Slf4j

可选参数

@ActiveProfiles("baseline") :表示项目启动参数为-baseline
@Transactional :回滚
import com.shimao.iot.common.entity.ResultListVO;
import com.shimao.iot.common.entity.ResultVO;
import com.shimao.iot.common.model.dict.vo.AreaDictGangVo;
import com.shimao.iot.common.model.dict.vo.AreaDictVo;
import com.shimao.iot.system.IotSystemApplication;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.WebApplicationContext;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author zhangtonghao
* @create 2022-02-16 11:00
*/
@ActiveProfiles("baseline")
@RunWith(SpringRunner.class)
@SpringBootTest(classes =IotSystemApplication.class, webEnvironment =SpringBootTest.WebEnvironment.DEFINED_PORT)
@AutoConfigureMockMvc
@Transactional
@Slf4j
class AreaDictionaryControllerTest {
    private MockMvc mockMvc;
    @Autowired
    private AreaDictionaryController controller;
    @Autowired
    private WebApplicationContext webApplicationContext;
    /*@BeforeEach  初始化数据
void setUp() throws Exception {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}*/
    @Test
    void getRegionDetail() {
        ResultListVO<AreaDictGangVo> regionDetail =controller.getRegionDetail("");
        System.out.println("======测试成功:" +regionDetail);
        String name ="华北";
        regionDetail =controller.getRegionDetail(name);
        Assert.assertNotNull(regionDetail);
        System.out.println("======测试成功:" +regionDetail);
    }
    @Test
    void testGetRegionDetail() {
        Long areaCode =100001L;
        ResultVO<AreaDictVo> regionDetail =controller.getRegionDetail(areaCode);
        Assert.assertNotNull(regionDetail);
        System.out.println("======测试成功:" +regionDetail);
    }
    @Test
    void getAreaTypeDetails() {
        Integer areaCode =100001;
        ResultListVO<AreaDictVo> resultListVO =controller.getAreaTypeDetails(areaCode);
        Assert.assertNotNull(resultListVO);
        System.out.println("======测试成功:" +resultListVO);
    }
    @Test
    void getSubrangeDetail() {
        Long areaCode =100001L;
        ResultListVO<AreaDictVo> resultListVO =controller.getSubrangeDetail(areaCode);
        Assert.assertNotNull(resultListVO);
        System.out.println("======测试成功:" +resultListVO);
    }
    @Test
    void getGangDetail() {
        Long areaCode =100001L;
        ResultVO<AreaDictGangVo> resultListVO =controller.getGangDetail(areaCode);
        Assert.assertNotNull(resultListVO);
        System.out.println("======测试成功:" +resultListVO);
    }
    @Test
    void findAreaDictList() {
        Long areaCode =100001L;
        List<Long> areaCodes =new ArrayList<>();
        areaCodes.add(areaCode);
        List<AreaDictVo> resultListVO =controller.findAreaDictList(areaCodes);
        Assert.assertNotNull(resultListVO);
        System.out.println("======测试成功:" +resultListVO);
    }
    @Test
    void findAreaDictParentMap() {
        Long areaCode =100001L;
        List<Long> areaCodes =new ArrayList<>();
        areaCodes.add(areaCode);
        Map<Long, AreaDictVo> resultListVO =controller.findAreaDictParentMap(areaCodes);
        Assert.assertNotNull(resultListVO);
        System.out.println("======测试成功:" +resultListVO);
    }
    @Test
    void queryProvinceAndCity() {
        ResultListVO<AreaDictVo> resultListVO =controller.queryProvinceAndCity();
        Assert.assertNotNull(resultListVO);
    }
}

4.启动测试:正常启动我就不说了说下如何查看覆盖率启动

首先需要安装junit插件,然后启动:

注意点:其实书写单元测试没有什么技巧,只有一个参数问题;你能保证参数正确就可以让测试覆盖率更高。这都需要看代码实现,所以不用妄想一键生成覆盖率达到百分之80啥的了,不存在的。下面还有一些可用的技巧和讲解,着急的可以不用看直接回去写代码去了。

三:扩展

某些对象类的单元测试:

/**

* 调用VO DTO POJO MODEL等服务通用方法
*/
@Test
public void testDto() {
    HeartDtoheartDto = newHeartDto();
    testGetAndSet(heartDto);
    heartDto.toString();
    heartDto.equals(newObject());
    heartDto.hashCode();
    AlllogDtoallLogDto = newAlllogDto();
    testGetAndSet(allLogDto);
    allLogDto.toString();
    allLogDto.equals(newObject());
    allLogDto.hashCode();
}
/**
* JavaBean属性名要求:前两个字母要么都大写,要么都小写
* 对于首字母是一个单词的情况,要么过滤掉,要么自己拼方法名
* f.isSynthetic()过滤合成字段
*/
private static void testGetAndSet(Object t) {
    try {
        Class modelClass =t.getClass();
        Object obj =modelClass.newInstance();
        Field[] fields =modelClass.getDeclaredFields();
        for (Fieldf :fields) {
            if (f.getName().equals("aLike") ||f.isSynthetic()) {
                continue;
            }
            PropertyDescriptorpd = newPropertyDescriptor(f.getName(), modelClass);
            Methodget =pd.getReadMethod();
            Methodset =pd.getWriteMethod();
            set.invoke(obj, get.invoke(obj));
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

断言列表:

-------------->assertTrue(String message, boolean condition)             要求condition == true
-------------->assertFalse(String message, boolean condition)            要求condition == false
-------------->assertEquals(String message, XXX expected,XXX actual) 要求expected期望的值能够等于actual
-------------->assertArrayEquals(String message, XXX[] expecteds,XXX [] actuals) 要求expected.equalsArray(actual)
-------------->assertNotNull(String message, Object object)          要求object!=null
-------------->assertNull(String message, Object object)             要求object==null
-------------->assertSame(String message, Object expected, Object actual)     要求expected == actual
-------------->assertNotSame(String message, Object unexpected,Object actual) 要求expected != actual
-------------->assertThat(String reason, T actual, Matcher matcher)  要求matcher.matches(actual) == true
-------------->fail(String message) 要求执行的目标结构必然失败,同样要求代码不可达,即是这个方法在程序运行后不会成功返回,如果成功返回了则报错

代码覆盖程度的度量方式是有很多种的,这里介绍一下最常用的几种:

1. 语句覆盖(StatementCoverage)

又称行覆盖(LineCoverage),段覆盖(SegmentCoverage),基本块覆盖(BasicBlockCoverage),这是最常用也是最常见的一种覆盖方式,就是度量被测代码中每个可执行语句是否被执行到了。这里说的是“可执行语句”,因此就不会包括像C++的头文件声明,代码注释,空行,等等。非常好理解,只统计能够执行的代码被执行了多少行。需要注意的是,单独一行的花括号{} 也常常被统计进去。语句覆盖常常被人指责为“最弱的覆盖”,它只管覆盖代码中的执行语句,却不考虑各种分支的组合等等。假如你的上司只要求你达到语句覆盖,那么你可以省下很多功夫,但是,换来的确实测试效果的不明显,很难更多地发现代码中的问题。

2. 判定覆盖(DecisionCoverage)

又称分支覆盖(BranchCoverage),所有边界覆盖(All-EdgesCoverage),基本路径覆盖(BasicPathCoverage),判定路径覆盖(Decision-Decision-Path)。它度量程序中每一个判定的分支是否都被测试到了。这句话是需要进一步理解的,应该非常容易和下面说到的条件覆盖混淆。因此我们直接介绍第三种覆盖方式,然后和判定覆盖一起来对比,就明白两者是怎么回事了。

3. 条件覆盖(ConditionCoverage)

它度量判定中的每个子表达式结果true和false是否被测试到了。

4. 路径覆盖(PathCoverage)

又称断言覆盖(PredicateCoverage)。它度量了是否函数的每一个分支都被执行了。这句话也非常好理解,就是所有可能的分支都执行一遍,有多个分支嵌套时,需要对多个分支进行排列组合,可想而知,测试路径随着分支的数量指数级别增加。

到此这篇关于springboot集成junit编写单元测试实战的文章就介绍到这了,更多相关springboot junit单元测试内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBoot环境下junit单元测试速度优化方式

    目录 1.提高单元测试效率 背景 2.单元测试如何执行 补充说明 3.项目中使用 4.优化单测思路 思路 5.实现方式 6.编码实现 6.1 Jetty作为服务启动 6.2 Tomcat作为容器启动 1.提高单元测试效率 背景 在项目提测前,自己需要对代码逻辑进行验证,所以单元测试必不可少. 但是现在的java项目几乎都是基于SpringBoot系列开发的,所以在进行单元测试时,执行一个测试类就要启动springboot项目,加载上下文数据,每次执行一次测试都要再重新加载上下文环境,这样就会很麻

  • SpringBoot与单元测试JUnit的结合操作

    目录 Juint版本说明 Junit5常见注解及其用法 在普通Maven项目中使用Junit 在Spring项目中使用Junit 在SpringBoot项目中使用Junit 有些人认为,写单元测试就是在浪费时间 ,写完代码,依然还是能够进行测试的.但是,还是建议写单元测试的,可以让你的条理更加清晰,而且当某个功能出现问题时,可能通过单元测试很容易的定位和解决问题. 本文主要总结下在Spring及SpringBoot项目中,使用单元测试时的方法.将JUnit4和JUnit5对比着来写,因为我发现我

  • SpringBoot+JUnit5+MockMvc+Mockito单元测试的实现

    目录 版本 项目结构 EchoServiceImpl EchoControllerNoMockitoTest EchoControllerMockTest 今天聊聊如何在 SpringBoot 中集成 Junit5.MockMvc.Mocktio.Junit5 是在 Java 栈中应用最广的测试框架,Junit4 一度霸榜. 升级到 Junit5 之后,除了增加 Java8 的很多特性,做了很多功能增强,在结构上做了优化调整,拆分了很多不同的模块,可以按需引入,比如: JUnit Platfor

  • 基于Springboot+Junit+Mockito做单元测试的示例

    前言 这篇文章介绍如何使用Springboot+Junit+Mockito做单元测试,案例选取撮合交易的一个类来做单元测试. 单元测试前先理解需求 要写出好的单测,必须先理解了需求,只有知道做什么才能知道怎么测.但本文主要讲mockito的用法,无需关注具体需求.所以本节略去具体的需求描述. 隔离外部依赖 Case1. 被测类中被@Autowired 或 @Resource 注解标注的依赖对象,如何控制其返回值 以被测方法 MatchingServiceImpl.java的matching(Ma

  • SpringBoot 单元测试JUnit的使用详解

    一.简介 JUnit是一款优秀的开源Java单元测试框架,也是目前使用率最高最流行的测试框架,开发工具Eclipse和IDEA对JUnit都有很好的支持,JUnit主要用于白盒测试和回归测试. 白盒测试:把测试对象看作一个打开的盒子,程序内部的逻辑结构和其他信息对测试人 员是公开的: 回归测试:软件或环境修复或更正后的再测试: 单元测试:最小粒度的测试,以测试某个功能或代码块.一般由程序员来做,因为它需要知道内部程序设计和编码的细节: 二.JUnit使用 1.pom.xml中添加JUnit依赖.

  • Springboot集成JUnit5优雅进行单元测试的示例

    为什么使用JUnit5 JUnit4被广泛使用,但是许多场景下使用起来语法较为繁琐,JUnit5中支持lambda表达式,语法简单且代码不冗余. JUnit5易扩展,包容性强,可以接入其他的测试引擎. 功能更强大提供了新的断言机制.参数化测试.重复性测试等新功能. ps:开发人员为什么还要测试,单测写这么规范有必要吗?其实单测是开发人员必备技能,只不过很多开发人员开发任务太重导致调试完就不管了,没有系统化得单元测试,单元测试在系统重构时能发挥巨大的作用,可以在重构后快速测试新的接口是否与重构前有

  • springboot集成junit编写单元测试实战

    目录 一:查看jar包版本号是否为junit4: 二:实战应用: 三:扩展 在做单元测试时,代码覆盖率常常被拿来作为衡量测试好坏的指标,甚至,用代码覆盖率来考核测试任务完成情况,比如,代码覆盖率必须达到80%或 90%.于是乎,测试人员费尽心思设计案例覆盖代码.用代码覆盖率来衡量,有利也有弊. 首先,让我们先来了解一下所谓的“代码覆盖率”.我找来了所谓的定义:代码覆盖率 = 代码的覆盖程度,一种度量方式. 一:查看jar包版本号是否为junit4: junit自身注解: @BeforeClass

  • Springboot集成kafka高级应用实战分享

    目录 深入应用 1.1 springboot-kafka 1.2 消息发送 1.2.1 发送类型 1.2.2 序列化 1.2.3 分区策略 1.3 消息消费 1.3.1 消息组别 1.3.2 位移提交 深入应用 1.1 springboot-kafka 1)配置文件 kafka: bootstrap-servers: 52.82.98.209:10903,52.82.98.209:10904 producer: # producer 生产者 retries: 0 # 重试次数 acks: 1 #

  • 详解springboot中junit回滚

    springboot中使用junit编写单元测试,并且测试结果不影响数据库. pom引入依赖 如果是IDE生成的项目,该包已经默认引入. <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency&g

  • Springboot使用Junit测试没有插入数据的原因

    从写Junit开始笔者就有一个疑问,为什么执行插入测试方法成功了但是数据库里却没有对应数据,那怎么测试的呢?今天查阅了资料找到了原因 1.Junit测试原理 springboot中使用junit编写单元测试默认是事物回滚的,这样测试的脏数据不影响数据库,即实际上是执行了对应的插入操作,但是完成操作后执行了事务回滚操作,从而数据库中没有对应数据. 2.关闭自动事务回滚 在对应的测试方法上添加@Rollback(false)关闭回滚. 补充知识:Spring Boot Junit无法执行问题汇总 S

  • JavaWeb实战之编写单元测试类测试数据库操作

    首先导入jar包 使用Mybatis generator生成,dao.entity.mappers 没有dataSource,我圈错了... jdbc.properties是数据库链接配置文件 sqlMapConfig.xml是Mybatis 配置文件 如何自动生成这些文件夹? 如下.右键generatorConfig -> 选择Run as -> 如何点击Run Mybatis Generator 新建MyBatisTool public class MybatisTool { public

  • SpringBoot集成ActiveMQ的实战全过程

    目录 前言 JMS规范 ActiveMQ介绍 Spring Boot集成ActiveMQ 创建项目并引入依赖 配置文件 队列模式实例 订阅模式实例 同时支持两种形式 其他事项 参考文章:  总结 前言 在项目开发的过程中我们经常会遇到类似的业务场景:用户申请提现,后台进行账务处理.发送提现短信.调用银行打款通道. 在这个过程中调用三方通道(短信或银行通道)都比较耗时,同时账务处理可能也是由专门的账务系统进行处理.那么,为了提高并发和相应速度,后面的三个操作都可以通过异步进行处理.这就用到了消息队

  • SpringBoot集成Graphql Query实战示例

    目录 概述 场景模拟 开发实战 创建一个SpringBoot项目 建立Java实体类 编写Schema文件 编写业务逻辑 配置Graphql 端点 测试 安装插件 查询 小结 概述 REST作为一种现代网络应用非常流行的软件架构风格受到广大WEB开发者的喜爱,在目前软件架构设计模式中随处可见REST的身影,但是随着REST的流行与发展,它的一个最大的缺点开始暴露出来: 在很多时候客户端需要的数据往往在不同的地方具有相似性,但却又不尽相同. 如同样的用户信息,在有的场景下前端只需要用户的简要信息(

  • springboot使用单元测试实战

    前言 springboot提供了 spirng-boot-starter-test 以供开发者使用单元测试,在引入 spring-boot-starter-test 依赖后: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope>

  • Springboot Mybatis-Plus数据库单元测试实战(三种方式)

      单元测试长久以来是热门话题,本文不会讨论需不需要写单测,可以看看参考资料1,我个人认为写好单测应该是每个优秀开发者必备的技能,关于写单测的好处在这里我就不展开讨论了,快速进入本文着重讨论的话题,如何写好数据库单测.   为什么要写数据库单测? 相信大家是不是有这样类似的经历,在写完复杂的sql语句后,自信满满的提测,发现很大一部分Bug都是因为sql语句出现问题了,要么少写逗号,要么漏了字段,悔不当初哇,为啥写完不多测测呢!   没关系!这就教你如何写数据库单测,让你轻松告别数据库相关bug

随机推荐