IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> Mockito:模拟测试框架的具体介绍与使用 -> 正文阅读

[开发测试]Mockito:模拟测试框架的具体介绍与使用

我是 ABin-阿斌:写一生代码,创一世佳话,筑一揽芳华。 如果小伙伴们觉得我的文章不错,记得一键三连哦。
在这里插入图片描述

一、什么是Mockito

Mockito 是一个强大的用于 Java 开发的模拟测试框架, 通过 Mockito 我们可以创建和配置 Mock 对象,进而简化有外部依赖的类的测试。

二、有什么作用:

提前创建测试,TDD(测试驱动开发)

  • 如果你创建了一个 Mock 那么你就可以在 service 接口创建之前写 Service Tests 了,这样你就能在开发过程中把测试添加到你的自动化测试环境中了。换句话说,模拟使你能够使用测试驱动开发。

团队可以并行工作

  • 这类似于上面的那点;为不存在的代码创建测试。但前面讲的是开发人员编写测试程序,这里说的是测试团队来创建。当还没有任何东西要测的时候测试团队如何来创建测试呢?模拟并针对模拟测试!
  • 这意味着当 service 接口需要测试时,实际上 QA 团队已经有了一套完整的测试组件;没有出现一个团队等待另一个团队完成的情况。这使得模拟的效益型尤为突出了。

你可以创建一个验证或者演示程序。

  • 由于Mocks 非常高效,Mocks 可以用来创建一个概念证明,作为一个示意图,或者作为一个你正考虑构建项目的演示程序。这为你决定项目接下来是否要进行提供了有力的基础,但最重要的还是提供了实际的设计决策。

隔离系统

  • 有时,你希望在没有系统其他部分的影响下测试系统单独的一部分。由于其他系统部分会给测试数据造成干扰,影响根据数据收集得到的测试结论。使用 mock 你可以移除掉除了需要测试部分的系统依赖的模拟。
  • 当隔离这些 mocks 后,mocks 就变得非常简单可靠,快速可预见。这为你提供了一个移除了随机行为,有重复模式并且可以监控特殊系统的测试环境。

三、具体如何使用:

  • 在使用 Mockito 测试框架时,我们需要提前在 idea 中装一个测试插件,这个插件会帮我们生成大部分的测试代码,从而减少我们的一个测试开发成本。

IntelliJ idea 需要安装的测试插件

在这里插入图片描述
当我们安装好这个插件后我们只需要选中我们想要测试的类——操作如下:

在这里插入图片描述
这里可以根据你们公司所规定的测试版本来,我这里用的是 JUnit5 和 Mockito

在这里插入图片描述

经过以上操作后,我们 ServiceImpl 中有几个方法,这个插件就会帮我们生成几个相对应的测试方法,当然这里我们还需要自己手动改一下

  • init()和 最下面那个方法是通用的,其方法根据自己的实际情况来测试就可以了。下面看不懂的注解可以去查一下主要是 Junit5 和 Mockito测试框架

3.1 Mockito的API介绍

3.2案例解析:

要测试的 DtMachineIncomeServiceImpl 实现类

@Service
public class DtMachineIncomeServiceImpl extends ServiceImpl<DtMachineIncomeMapper, DtMachineIncomeEntity> implements DtMachineIncomeService {

    @Autowired
    private DtMachineAddressIncomeDayService dtMachineAddressIncomeDayService;
    @Autowired
    private DtMachineInfoService dtMachineInfoService;

    @Override
    public BigDecimal profitByTeamsAndCurrency(List<Long> teamIds, String currencyMark) {
        DynamicTableParser.setId(currencyMark);
        List<DtMachineIncomeEntity> machineIncomeEntityList = this.list(Wrappers.lambdaQuery(DtMachineIncomeEntity.class)
                .in(DtMachineIncomeEntity::getOrganizationId, teamIds));
        return machineIncomeEntityList.parallelStream().map(DtMachineIncomeEntity::getActualTotalIncome).reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    @Override
    public DtMachineIncomeEntity getOneByOrganizationIdAndMachineId(Long organizationId, Long machineIdId) {
        return this.getOne(Wrappers.lambdaQuery(DtMachineIncomeEntity.class)
                .eq(DtMachineIncomeEntity::getOrganizationId, organizationId)
                .eq(DtMachineIncomeEntity::getMachineId, machineIdId)
                .last(MybatisPlusConst.LIMIT_1));
    }


    @Override
    public boolean saveDtMachineIncome(DtMachineIncomeEntity entity) {
        return this.save(entity);
    }

    @Override
    public boolean updateByDtMachineIncomeId(DtMachineIncomeEntity entity) {
        return this.updateById(entity);
    }

    @Override
    public List<DtMachineIncomeEntity> listByTeamId(Long teamId) {
        return this.list(Wrappers.lambdaQuery(DtMachineIncomeEntity.class)
                .eq(DtMachineIncomeEntity::getOrganizationId, teamId));
    }

    @Override
    public DtMachineIncomeEntity lastTimeByTeamIds(List<Long> teamIdsByUserId) {
        return this.getOne(Wrappers.lambdaQuery(DtMachineIncomeEntity.class)
                .in(DtMachineIncomeEntity::getOrganizationId, teamIdsByUserId)
                .orderByDesc(DtMachineIncomeEntity::getUpdateTime)
                .last(MybatisPlusConst.LIMIT_1));
    }

    @Override
    public void updateMachineProfits(Long organizationId, Long machineIdd, DateTime dateTime, Integer type) {
        DynamicTableParser.setId(CurrencyMarkEnum.ETH.getMark());
        DtMachineIncomeEntity machineIncomeEntity = this.getOne(Wrappers.lambdaQuery(DtMachineIncomeEntity.class)
                .eq(DtMachineIncomeEntity::getMachineId, machineIdd)
                .eq(DtMachineIncomeEntity::getOrganizationId, organizationId));
        if (ObjectUtil.isEmpty(machineIncomeEntity)) {
            return;
        }
        DtMachineAddressIncomeDayEntity dtMachineAddressIncomeDayEntity = dtMachineAddressIncomeDayService.getOne(Wrappers.lambdaQuery(DtMachineAddressIncomeDayEntity.class)
                .eq(DtMachineAddressIncomeDayEntity::getOrganizationId, organizationId)
                .eq(DtMachineAddressIncomeDayEntity::getMachineId, machineIdd)
                .between(DtMachineAddressIncomeDayEntity::getDayTime, DateUtil.beginOfDay(dateTime), DateUtil.endOfDay(dateTime)));

        // 1-移动至  2-删除
        if (type == 1) {
            machineIncomeEntity.setTheoryIncome(BigDecimal.ZERO);
            if (ObjectUtil.isNotEmpty(dtMachineAddressIncomeDayEntity)) {
                dtMachineAddressIncomeDayEntity.setTheoryIncome(BigDecimal.ZERO);
                dtMachineAddressIncomeDayEntity.setUpdateTime(dateTime);
                dtMachineAddressIncomeDayService.updateById(dtMachineAddressIncomeDayEntity);
            }
        }
        machineIncomeEntity.setActualComputingPower("0");
        machineIncomeEntity.setTwentyFourAvgComputingPower("0");
        machineIncomeEntity.setUpdateTime(dateTime);
        this.updateById(machineIncomeEntity);
    }

    @Override
    public List<DtMachineIncomeEntity> listByTeamIdNoRepeat(Long teamId) {
        List<DtMachineIncomeEntity> returnList = new ArrayList<>();
        List<DtMachineInfoEntity> machineInfoList = dtMachineInfoService.listByTeamId(teamId);
        Map<Long, Long> count = machineInfoList.parallelStream().map(x -> x.getAddressId())
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
        List<DtMachineInfoEntity> noRepeatAddressIds = new ArrayList<>();
        count.forEach((k, v) -> {
            if (ObjectUtil.isNotEmpty(k)) {
                DtMachineInfoEntity dtMachineInfoEntity = dtMachineInfoService.listByTeamIdAndAddressId(teamId, k);
                noRepeatAddressIds.add(dtMachineInfoEntity);
            }
        });
        if (ObjectUtil.isNotEmpty(noRepeatAddressIds)) {
            for (DtMachineInfoEntity infoEntity : noRepeatAddressIds) {
                DtMachineIncomeEntity oneByOrganizationIdAndMachineId = this.getOneByOrganizationIdAndMachineId(infoEntity.getOrganizationId(), infoEntity.getId());
                if (ObjectUtil.isNotEmpty(oneByOrganizationIdAndMachineId)) {
                    returnList.add(oneByOrganizationIdAndMachineId);
                }
            }
        }
        return returnList;
    }

    @Override
    public List<DtMachineIncomeEntity> listByTeamIds(List<Long> teamIds) {
        return this.list(Wrappers.lambdaQuery(DtMachineIncomeEntity.class)
                .in(DtMachineIncomeEntity::getOrganizationId, teamIds));
    }
}

测试类:下面的代码结合上面实现代码看会好懂一点

@ExtendWith({SpringExtension.class, ExtentUtils.class})
class DtMachineIncomeServiceImplTest {
	//除了我们测试类本身要真实的其它都可以进行 mock 模拟
    @MockBean
    DtMachineAddressIncomeDayService dtMachineAddressIncomeDayService;
    @MockBean
    DtMachineInfoService dtMachineInfoService;
    @MockBean
    DtMachineIncomeMapper dtMachineIncomeMapper;
    //这个必须要真实的,因为这个是我们要测试的主体类
    @Autowired
    DtMachineIncomeServiceImpl dtMachineIncomeServiceImpl;

    @BeforeAll
    public static void init() {
        TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""), DtMachineIncomeEntity.class);
    }

    @Test
    @DisplayName("根据组织id集合,币种返回实际总收益")
    void testProfitByTeamsAndCurrency() {
        BigDecimal result = dtMachineIncomeServiceImpl.profitByTeamsAndCurrency(Arrays.<Long>asList(Long.valueOf(1)), "currencyMark");
        Assertions.assertEquals(new BigDecimal(0), result);
    }

    @Test
    @DisplayName("根据矿机id,组织id返回一天记录")
    void testGetOneByOrganizationIdAndMachineId() {
    	//模拟当第一次当用这个方法时,返回这个:new DtMachineIncomeEntity()
    	//any():表示所有、任何
        when(dtMachineIncomeServiceImpl.getOne(any())).thenReturn(new DtMachineIncomeEntity());
        DtMachineIncomeEntity result = dtMachineIncomeServiceImpl.getOneByOrganizationIdAndMachineId(Long.valueOf(1), Long.valueOf(1));
        //判断是否相等
        Assertions.assertEquals(new DtMachineIncomeEntity(), result);
    }
    
	@Test
    @DisplayName("保存对象")
    void testSaveDtMachineIncome() {
    	//模拟调用方法,返回 1
        when(dtMachineIncomeMapper.insert(any())).thenReturn(1);
        boolean result = dtMachineIncomeServiceImpl.saveDtMachineIncome(new DtMachineIncomeEntity());
        Assertions.assertEquals(true, result);
    }

    @Test
    @DisplayName("根据id修改")
    void testUpdateByDtMachineIncomeId() {
        when(dtMachineIncomeMapper.updateById(any())).thenReturn(1);
        boolean result = dtMachineIncomeServiceImpl.updateByDtMachineIncomeId(new DtMachineIncomeEntity());
        Assertions.assertEquals(true, result);
    }

    @Test
    @DisplayName("根据小组集合返回列表")
    void testListByTeamId() {
        when(dtMachineIncomeServiceImpl.list(any())).thenReturn(Arrays.<DtMachineIncomeEntity>asList(new DtMachineIncomeEntity()));
        List<DtMachineIncomeEntity> result = dtMachineIncomeServiceImpl.listByTeamId(Long.valueOf(1));
        Assertions.assertEquals(Arrays.<DtMachineIncomeEntity>asList(new DtMachineIncomeEntity()), result);
    }

    @Test
    @DisplayName("返回最新更新时间")
    void testLastTimeByTeamIds() {
        when(dtMachineIncomeServiceImpl.getOne(any())).thenReturn(new DtMachineIncomeEntity());
        DtMachineIncomeEntity result = dtMachineIncomeServiceImpl.lastTimeByTeamIds(Arrays.<Long>asList(Long.valueOf(1)));
        Assertions.assertEquals(new DtMachineIncomeEntity(), result);
    }

    @Test
    @DisplayName("ETH删除(移动至)矿机收益算力操作")
    void testUpdateMachineProfits() {
        dtMachineIncomeServiceImpl.updateMachineProfits(Long.valueOf(1), Long.valueOf(1), null, Integer.valueOf(0));
    }

    @Test
    @DisplayName("根据小组集合返回列表")
    void testListByTeamIdNoRepeat() {
        DtMachineInfoEntity mock = JMockData.mock(DtMachineInfoEntity.class);
        List<DtMachineInfoEntity> dtMachineInfos = new ArrayList<>();
        dtMachineInfos.add(mock);
        when(dtMachineInfoService.listByTeamId(any())).thenReturn(dtMachineInfos);
        when(dtMachineInfoService.listByTeamIdAndAddressId(any(), any())).thenReturn(mock);
        DtMachineIncomeEntity mock1 = JMockData.mock(DtMachineIncomeEntity.class);
        when(dtMachineIncomeServiceImpl.getOne(any())).thenReturn(mock1);
        List<DtMachineIncomeEntity> result = dtMachineIncomeServiceImpl.listByTeamIdNoRepeat(Long.valueOf(1));
        Assertions.assertEquals(Arrays.<DtMachineIncomeEntity>asList(mock1), result);
    }

    @Test
    @DisplayName("根据组织ID列表查询在矿机收益中是否存在数据")
    void testListByTeamIds() {
        when(dtMachineIncomeServiceImpl.list(any())).thenReturn(Arrays.<DtMachineIncomeEntity>asList(new DtMachineIncomeEntity()));
        List<DtMachineIncomeEntity> result = dtMachineIncomeServiceImpl.listByTeamIds(Arrays.<Long>asList(Long.valueOf(1)));
        Assertions.assertEquals(Arrays.<DtMachineIncomeEntity>asList(new DtMachineIncomeEntity()), result);
    }




    @TestConfiguration
    static class dtMachineIncomeServiceImplTestContextConfiguration {
        @Bean
        public DtMachineIncomeServiceImpl dtMachineIncomeService() {
            return new DtMachineIncomeServiceImpl();
        }
    }
}

总结:

  • 我们需要测试的哪个类必须是真实的,其他所有的都可以进行模拟,比如上面代码中只有 dtMachineIncomeServiceImpl 去调用的方法时真实的,在它只上的其他方法都是可以 mock 的。
  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-07-13 17:47:30  更:2021-07-13 17:47:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/5 23:01:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码