快试试用Mockito做做单元测试吧

1600 篇文章 75 订阅
1439 篇文章 116 订阅

什么是单元测试?

在计算机编程中,单元测试又称为模块测试  ,是针对程序模块的最小单位。来进行正确性检验的测试工作。程序单元是应用的最小可测试部件。 ---摘自维基百科

说人话就是我们在项目中的每一个业务方法,都是一个小模块,小单元,应该进行正确性检测。

单元测试的目的是什么?

测试的目的是为了验证业务逻辑是否正确,方法的各种形式输入是否能够返回正确的输出。

如何进行单元测试

Java项目中单元测试的框架有很多,本文中将使用Mockito框架来给大家进行演示。 为什么选择Mockito框架?SpringBoot默认的Mock框架就是Mockito,只需要依赖spring-boot-starter-test。

之前我相信大家都用过junit来进行单元测试,Mockito也要配合junit来一起使用。那现在为什么不只用junit来进行单测呢? 原因是业务中的依赖问题!当我们执行一个稍微复杂些的业务方法时,会发现它往往会调用很多其他依赖的远程接口来配合才能完成方法的执行,如果使用junit,那么我们就要构造一个完整的依赖出来,当依赖很多时这是非常麻烦的。

Mockito是GitHub上使用最广泛的Mock框架,并与JUnit结合使用。Mockito框架可以创建和配置mock对象.使用Mockito简化了具有外部依赖的类的测试开发

1. 单元测试规范

我们所有的测试类都应该写在test包中,如下

针对于每一个测试业务方法我们都应该进行测试。创建的测试类用测试的类名加上后缀Test来命名,如UserServiceTest。

2. Mockito的使用

我们测试的目的是为了验证业务逻辑是否正确,尽可能的避免该业务方法依赖的其他类造成的困扰。而mockito就可以模拟这些调用的过程,自定义返回值。其核心使用了代理机制

由于mockito的方法都是静态方法,因此我们可以将静态方法全部导入

import static org.mockito.Mockito.*;
复制代码

看看导入方法和没有导入方法的区别:

Mockito.when(...)   导入前,必须通过类名来调用
when(...)   导入静态方法后可以直接使用
复制代码

首先我们来看核心的三个注解:

  1. 在测试类上标注注解:
@RunWith(MockitoJUnitRunner.class)
复制代码
  1. 将要测试的具体实现类作为属性引入进来,并标注注解。
@InjectMocks  
比如需要测试UserService,找到它的实现类UserServiceImpl,作为字段引入进来,  
并标注该注解。
复制代码
  1. 在需要依赖到的其他类字段上标注注解
@Mock   // 该注解用于模拟依赖类
复制代码

2.1 制作模拟调用:

我们可以创建两种对象,一种是mock,一种是spy。这两种对象的区别如下:

1.得到的对象同样可以进行“监管”,即验证和打桩。

2.如果不对spy对象的methodA打桩,那么调用spy对象的methodA时,会调用真实方法。

3.如果不对mock对象的methodA打桩,将doNothing,且返回默认值(null,0,false)。

我们用代码来实现一下。

/**
 *  mock出来的数据不打桩测试的话默认所有操作返回null == 打桩之后就返回打桩设置的值
 *  spy出来的数据不打桩测试的话将会执行真实的方法 == 打桩之后执行打桩设置的值
 */
@Test
public void test1() {
    List<Integer> spylist = spy(ArrayList.class);  //创建一个spy对象
    List<Integer> mocklist = mock(ArrayList.class);  // 创建一个mock对象
    spylist.add(1);
    mocklist.add(1);
    System.out.println("spylist打桩之前:"+spylist.get(0));
    System.out.println("mocklist打桩之前:"+mocklist.get(0));

    when(spylist.get(0)).thenReturn(100);
    when(mocklist.get(0)).thenReturn(100);
    System.out.println("spylist打桩后测试:"+spylist.get(0));
    System.out.println("mocklist打桩后测试:"+mocklist.get(0));

    System.out.println("doreturn:"+spylist.get(0));
    System.out.println("spy远程调用不打桩测试:"+pushMsgPlanMapper.getById(any()));

    System.out.println("mock对象不打桩测试:"+mocklist.add(1));
}
复制代码

结果如下:

2.2 打桩

什么是打桩?就是我们通过模拟某个方法的执行流程,自己设置该方法调用后会返回的值。 我们把要测试类依赖的所有其他类通过@mock注解来模拟出来后,就用打桩来模拟执行,这样就不用管测试类所需要的那些依赖了。

流程如下:

when(执行的方法调用).thenReturn(期望返回结果);   
复制代码

打桩后在执行测试类的过程中遇见了这个方法调用,那么就会直接返回我们设置的期望返回结果。可以看一下上面举出来的例子。

when方法后面可以跟上多个thenReturn,每一个thenReturn方法都代表了方法调用的结果。如

when(执行的方法调用).thenReturn(期望返回结果1).thenReturn(期望返回结果2).thenReturn(期望返回结果3);  
复制代码

当该方法被调用多次时,第一次调用将返回结果1,第二次调用返回结果2... 依次类推。

总结

单元测试的目的就是为了检查我们业务的逻辑正确性。mockito框架提供了数据模拟(mock) 和“打桩”的功能,让我们可以自定义方法的返回结果,减少测试类中的其他依赖类给我们造成的影响,非常好用,赶紧用起来吧!

最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走


在此特意为大家准备了一份13G的超实用干货学习资源,涉及的内容非常全面,涵盖功能测试、Python编程语言,接口测试、UI自动化测试、性能测试......包括软件学习路线图,50多天的上课视频、16个突击实战项目,80余个软件测试用软件,37份测试文档,70个软件测试相关问题,40篇测试经验级文章,上千份测试真题分享,还有2022软件测试面试宝典,还有软件测试求职的各类精选简历,希望对大家有所帮助…..关注下方公众号免费获取~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值