首页 > 其他分享 >大白话单元测试之mock测试

大白话单元测试之mock测试

时间:2024-08-24 12:52:28浏览次数:13  
标签:xyDrugStandardDao 大白话 单元测试 mock 测试 注解 方法 public Mock

文章目录

一、什么是 Mock 测试

Mock通常是指,在测试一个对象A时,我们构造一些假的对象来模拟与A之间的交互,而这些Mock对象的行为是我们事先设定且符合预期。
这什么意思呢?
就是指在测试一个单元方法的时候,我们不想加载其他的类,默认其他类的功能是正常的,只测试这个方法。
好吧,我知道其实还是不太明白,那么请看示例

二、传统的单元测试Junit Test

首先看一下junit的单元测试是这样的,spring boot项目导入相关的依赖之后,
在测试类的上方注入两个注解,声明这是一个test类

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {WebApplication.class})
public class BaseTest {
}

单元方法是下面这样的,通过@Resource注解将matchSourceScoreService注入进来

    @Resource
    private MatchSourceScoreService matchSourceScoreService;
    
    @Test
    public void saveMatchSourceScore(){
        MatchSourceScore matchSourceScore = matchSourceScoreService.selectById(6L);
        matchSourceScore.setStandardCode(10d);
        matchSourceScore.setUpdateBy("TEST_1221001");
        XyResultModel<Long> resultModel = matchSourceScoreService.saveMatchSourceScore(matchSourceScore);
        Assert.assertTrue(true);
    }

测试会发现,我们启动这个test类的时候会将整个项目启动起来,如果项目过大,每次单测一个test方法都会花费很长的时间

那么mock测试与junit测试有什么区别呢?

三、Mock测试(对比junit测试)

首先看一下这个测试类

@RunWith(MockitoJUnitRunner.class)
public class UpdateStandardCodeListenerTest {

    @InjectMocks
    private UpdateStandardCodeService updateStandardCodeService;
    @Mock
    private XyDrugStandardDao xyDrugStandardDao;

    private final StandardCodeExcelDTO standardCodeExcelDTO = new StandardCodeExcelDTO();

    @Before
    public void init() {
        standardCodeExcelDTO.setStandardCode("00000000000000");
        standardCodeExcelDTO.setApprovalNum("国食健字G20220206");
        standardCodeExcelDTO.setStrength("默认");
        standardCodeExcelDTO.setGenericName("百合康牌越橘叶黄素软胶囊");
        standardCodeExcelDTO.setXyEntManufacturerName("山东威海百合生物技术股份有限公司");
    }

    @Test
    public void testHandleStandardCodeByInputDTO1() throws CheckArgsException {
        when(xyDrugStandardDao.selectList(any())).thenReturn(null);
        updateStandardCodeService.handleStandardCodeByType(standardCodeExcelDTO, 4, "sys");
        verify(xyDrugStandardDao, times(1)).insert(any());
    }

看上去似乎和junit测试没啥区别,都需要在类上注入@RunWith注解,单元方法也是用@Test注解,
但是有变化的是:

  • 有一些方法用@InjectMocks注解,有些方法用@Mock注解。
  • 单元方法中有when。。。、verify。。。
  • 并不需要启动整个项目,只会单独运行这个方法

四、Mock详解

1.@InjectMocks和@Mock用法

这两个注解也是为了引用类中方法,将其托管给mock管理,
比如:

  • 我的目的是为了测试updateStandardCodeService类中的handleStandardCodeByType方法,那么就需要将其注解为@InjectMocks。
  • 那么被@Mock注解注入的方法是handleStandardCodeByType方法中用到了xyDrugStandardDao这个类中的selectList方法去查数据库,被这个注解注入后,并不会真的去发出sql语句去查询数据库,而是根据某种规则,返回特定的值。

handleStandardCodeByType方法:
可以看到方法中有selectList和insert两个数据库的交互操作

public void handleStandardCodeByType(StandardCodeExcelDTO standardCodeExcelDTO, int type, String operator) {
		Wrapper<XyDrugStandard> wrapper = new EntityWrapper<>();
        List<XyDrugStandard> xyDrugStandards = xyDrugStandardDao.selectList(wrapper);
        if (CollectionUtils.isEmpty(xyDrugStandards)) {
           xyDrugStandardDao.insert(xyDrugStandard);
        }
}

2.when用法

    when(xyDrugStandardDao.selectList(any())).thenReturn(null);

这就是一条规则,对于xyDrugStandardDao类的selectList方法,any()就是参数不管是什么,都会返回null。

3.verify用法

	verify(xyDrugStandardDao, times(1)).insert(any());

这是一条验证规则,验证xyDrugStandardDao的insert方法,不管参数是什么,有没有被执行1次,没有的话就报错,相当于断言Assert。

五、Mock其他常用用法

1.如何初始化数据

像我上面的那种方法,用@Before注解,初始化你的变量值,会在test方法执行前运行。

2.初始化service类中的Apollo配置

	@Test
    public void testHandleStandardCodeByInputDTO1() throws CheckArgsException {
    	setField("manufactureNameValidLength", 4);
    }

public void setField(String fieldName, Object value){
        Field field = XyDrugMasterCodeServiceImpl.class.getDeclaredField(fieldName);
        field.setAccessible(true);
        field.set(xyDrugMasterCodeService, value);
    }

比如我想给XyDrugMasterCodeServiceImpl类中的Apollo配置manufactureNameValidLength赋初值4。
就可以使用反射的方式,给配置赋初值

3.Assert.assertEquals用法

Assert.assertEquals("c", testList.get(0));

声明断言,testList的get(0)和字符串c相等。

还有一些其他用法可以参考官网https://site.mockito.org/

标签:xyDrugStandardDao,大白话,单元测试,mock,测试,注解,方法,public,Mock
From: https://blog.csdn.net/weixin_45404884/article/details/140661780

相关文章

  • Python编码系列—Python单元测试的艺术:深入探索unittest与pytest
    ......
  • 公司最大的内卷,偷偷做单元测试
    一位读者在看过我的《理解这八大优势,才算精通单元测试》后,问我:知道单元测试有好处,但实在没空写。看完文章后又想重新落实一下,有没有啥写好单元测试的技巧?这位读者绝对不是第一个和我抱怨单元测试的人。这很好理解,中国互联网公司太多太卷,想要抢夺市场就要推出不同功能,而这些压力一......
  • WebAPI中写单元测试
    首次在WebAPI中写单元测试xUnit这次我使用的是xUnit测试框架,而不是VS自带的MSTest框架。在添加新建项目时选择xUnit测试项目就行了。目前只体验到了一个差别,即xUnit可以使用特性向测试方法传参,而不用在测试方法中一个赋值语句一个个去定义参数,这是比较方便的。单元测试有一个......
  • 大白话讲【3.1】redhat 9 -LVM
    LVM技术出现由来  说白了,就是文件系统容量怎么实现无感伸缩。定义:LVM(LogicalvolumeManager)逻辑卷管理通过将底层物理硬盘抽象封装起来,以逻辑卷的形式表现给上层系统,逻辑卷的大小可以动态调整,而且不会丢失现有数据。新加入的硬盘也不会改变现有上层的逻辑卷。  L......
  • mavn 执行 junit 单元测试的结果为 Tests run: 0, Failures: 0, Errors: 0, Skipped:
    mavn执行junit单元测试的结果为Testsrun:0,Failures:0,Errors:0,Skipped:0  [INFO]---surefire:3.2.5:test(default-test)@joyupx-trade---[INFO]Usingautodetectedproviderorg.apache.maven.surefire.junitplatform.JUnitPlatformProvider[INFO][INF......
  • 大白话讲【1.1】redhat 9采用nmtui快速配置Ipv4(网卡已有配置文件前提下)
    0.环境查看:[root@lili~]#uname-aLinuxlili5.14.0-70.13.1.el9_0.x86_64#1SMPPREEMPTThuApr1412:42:38EDT2022x86_64x86_64x86_64GNU/Linux[root@lili~]#ifconfig|head-2ens160:flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu1500     ......
  • 深入探究 Java 中的单元测试 Mock 技术
    在软件开发中,单元测试是确保代码质量和稳定性的重要手段。而Mock技术在单元测试中扮演着至关重要的角色,它能够帮助我们隔离外部依赖,更有效地对单个模块进行测试。本文将深入探讨Java中的单元测试Mock技术。一、单元测试与Mock技术概述单元测试是对软件中的最小可测试......
  • 深入理解单元测试:技巧与最佳实践
    之前分享过如何快速上手开源项目以及如何在开源项目里做集成测试,但还没有讲过具体的实操。今天来详细讲讲如何写单元测试。......
  • 对C工程使用GTest与Gmock函数未定义(undefined reference)排错记录
    在使用Gtest过程中出现了一些被测参数和函数未定义的问题调了三天很是头疼1、对象只申明未定义在配置文件中该结构体数组已经被定义完成,错误排除2、使用对象的错误定义(签名不匹配)  C++提供了函数重载,当函数的声明与调用时,输入参数与声明是不同时会报undefinedrefer......
  • 单元测试框架 powermock
    单元测试框架powermock  在pom.xml加入依赖包:<dependency><groupId>org.powermock</groupId><artifactId>powermock-api-mockito2</artifactId><version>${powermock.version}</version><scope>test</scope&......