junit 单元测试-java

本文详细介绍了JUnit单元测试框架及其与Spring Boot的整合使用方法,包括常见注解、断言判断等内容,并通过示例展示了如何引入相关依赖。此外,还深入探讨了PowerMock的使用技巧,包括打桩、常用命令及方法。


前言

Junnit 使用及总结。


一、Junnit 介绍

Junit单元测定义:单元测试是对软件组成单元进行测试,其目的是检验软件基本组成单位的正确性,测试的对象是软件设计的最小单位:函数

单元测试目的

  1. 可以快速速地进行回归测试
  2. TDD 是Test-Driven Development(测试驱动开发)
  3. 规范代码编写,使用最小单元定义方法

使用基础

junit结合spring使用,主要使用注解方式进行配置运行。基于一个测试对象(方法函数)有一个或者多个的测试用例,用断言方式判断多场景下运行结果是否符合期望。后续可结合power mock 构架多场景测试。

常用注解

注解作用作用域
@Test表示方法是测试方法。但是与JUnit4的@Test不同,他的职责非常单一不能声明任何属性,拓展的测试将会由Jupiter提供额外测试方法
@ParameterizedTest表示方法是参数化测试方法
@RepeatedTest表示方法可重复执行方法
@DisplayName为测试类或者测试方法设置展示名称方法
@BeforeEach表示在每个单元测试之前执行方法
@AfterEach表示在每个单元测试之后执行方法
@BeforeAll表示在所有单元测试之前执行方法
@AfterAll表示在所有单元测试之后执行方法
@Ignore表示测试类或测试方法不执行,方法
@Timeout表示测试方法运行如果超过了指定时间将会返回错误方法
@ExtendWith为测试类或测试方法提供扩展类引用 方法
@ValueSource为参数化测试指定入参来源,支持八大基础类以及String类型,Class类型方法
@NullSource表示为参数化测试提供一个null的入参方法
@EnumSource表示为参数化测试提供一个枚举入参方法
@CsvFileSource表示读取指定CSV文件内容作为参数化测试入参方法
@MethodSource表示读取指定方法的返回值作为参数化测试入参(注意方法返回需要是一个流)方法
@Runwith放在测试类名之前,用来确定这个类怎么运行的。也可以不标注,会使用默认运行器
@SpringBootTest整合springboot时使用,必要
@FixMethodOrder定义方法的执行顺序,下面会说到

断言判断

主要是org.junit.Assert 类进行断言判断结果是否等同于期望。主要测试点有一下情况

  • 方法正确性判断。是否正常返回数据
  • 数据结构判断。是否存在空指针,数组越位情况
  • 边界判断(多种情况,根据传入类型选择)
    • 变量无赋值(null)
    • 变量是数值或字符
    • 主要边界:最大值,最小值
    • 溢出边界:在边界外面取值+/-1
    • 临近边界:在边界值之内取值+/-1
    • 字符串的应用长度测试
    • 目标集合的类型和应用边界
  • 集合的次序
  • 异常数据处理是否影响系统运行。事务处理等

power mock基础使用

  • powerMock解决的问题
    PowerMock主要用于打桩。比如:方法A的参数需要传入实例B,方法A需要调用B的某个方法B.C()。方法C因为耗时长或者根本没有实现或者其他不方便在单元测试中实现等原因,需要伪造返回,此时PowerMock即可派上用场。可以很好使用测试驱动开发的编程逻辑

  • 常用命令
    @RunWith(PowerMockRunner.class) :作用于再类上 使用powerMock
    @PrepareForTest( { YourClass.class }):作用于再类上 ,对于静态,final 类使用,用于mock 当前类实例化对象,可以以=是多个
    @PowerMockIgnore(“javax.management.*”)::作用于再类上 ,忽略类异常

@mock : mock 接口使用,和@Autowired 类似
@InjectMocks:mock l类使用 和mock 类似,不过使用的是类非接口

  • 主要方法

PowerMockito.when(方法).thenReturn(返回值);
因为主要用于打桩,方法可以是空方法,返回值即这个接口的返回值
PowerMockito.mockStatic(youClass.class)
加载方法
方法有很类型,可以自行测试。

二、使用步骤

1.引入库

代码如下(示例):

//junit 
<dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-module-junit4</artifactId>
            <version>2.0.9</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-api-mockito2</artifactId>
            <version>2.0.9</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>net.bytebuddy</groupId>
            <artifactId>byte-buddy</artifactId>
            <version>1.12.8</version>
        </dependency>
        <dependency>
            <groupId>net.bytebuddy</groupId>
            <artifactId>byte-buddy-agent</artifactId>
            <version>1.12.8</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.objenesis</groupId>
            <artifactId>objenesis</artifactId>
            <version>3.2</version>
            <scope>test</scope>
        </dependency>

## 2.代码示例

```java

@RunWith(SpringRunner.class)
@SpringBootTest
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class CalcLogServiceImplTest {


    @Before
    public void before() {
        System.out.println("before .......");
    }

    @After
    public void afterAll() {
        System.out.println("after .......");
    }


    @Autowired
    private ICalcLogService calcService;

    @Test
    @DisplayName("计算获取数据入口")
    public void calcResult() {
        String str = Stream.of("2,3,5,1,2,9").collect(Collectors.joining(","));
        for (int i = 0; i < ChartType.values().length; i++) {
            String s = calcService.calcResult(ChartType.values()[i], str, null);
            System.out.println(s);
        }
    }

    @Test
    @DisplayName("计算保存整个接口,最后测试、最后整合再测试")
    public void calcData() {
        calcService.calcData();
    }
}

FixMethodOrder:用来定义操作顺序。
NAME_ASCENDING(MethodSorter.NAME_ASCENDING) //名字排序
JVM((Comparator)null) //按照JVM得到的方法顺序,也就是代码中定义的方法顺序
DEFAULT(MethodSorter.DEFAULT); 默认,以确定但不可预期的顺序执行

查看代码覆盖率:
在这里插入图片描述

这三个地方都可以

powerMock 代码


@RunWith(PowerMockRunner.class)
@PowerMockIgnore("javax.management.*")
@PrepareForTest({NumberUntil.class})
public class NumberUntilTest {
    @Before
    public void before(){

    }
    @Test
    public void getRandom() {
        //大于0 小于一百
        for (int i = 0; i <100 ; i++) {
            PowerMockito.mockStatic(NumberUntil.class);
            PowerMockito.when(NumberUntil.getRandom(false,100)).thenReturn(-2);
            int random = NumberUntil.getRandom(false, 100);//这时候,返回值是-2.也跟没有走方法
            System.out.println(random);
            Assert.assertTrue((random>=0&&random<=100));
        }
        //正数或者负数 小于一百 大于负100
        for (int i = 0; i <100 ; i++) {
            int random = NumberUntil.getRandom(true, 100);
            System.out.println(random);
            Assert.assertTrue((random > -100 && random < 100));
        }
    }
}

代码地址

https://gitee.com/kissingthefire/junitTest .


总结

PowerMock 还需要多更多的时间去了解,总结使用经验,从而提高代码质量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值