首页 > 其他分享 >单元测试 Mock不Mock?

单元测试 Mock不Mock?

时间:2024-09-02 09:51:47浏览次数:10  
标签:mocked 单元测试 update 调用 测试 Mock

文章目录

前言

前段时间,我们团队就单元测试是否采用 Mock 进行了一番交流,各有各的说法。本文就单元测试 Mock不Mock 给出我的观点,欢迎各位同仁提出不同的意见,共同探讨、相互交流。

单元测试没必要?

我见过好多不写单元测试的项目,大多给出的原因都是:“没必要”、“浪费时间”、“get不到单测的作用”,这样的项目要么是小规模,要么就是头铁。

本人之前也有相同的观点…

单元测试在软件开发过程中还是非常重要的,除了可以提高代码的质量,在引入CI/CD后的自动化测试环节可以起到快速部署、交付作用。难道每次上线都需要“点点点”测试?这一点,我想经历过的人都深有体会。

Mock不Mock?

那什么是Mock?

什么是Mock?

简单来说,Mock就是模拟目标代码的行为,在实际测试过程中代替真实的调用目标。如下图

这样做的意义何在?

Mock的意义何在?

试想一下,单元测试中如果出现以下几个问题应该怎么办?

  1. 涉及到的DB操作、网络调用等单元测试产生的数据属不属于垃圾数据?会不会影响业务?
  2. 发布/部署生产环境的过程中,错误地执行了单元测试引起生产问题怎么办?
  3. CI过程中的测试环节花费时间太长怎么办?会不会影响集成交付?

以上几个问题我想大部分开发人员都经历过,那如何避免这些问题?我想Mock就是最好的一种方式。

如果将涉及到的外部操作,例如DB操作、网络调用等行为进行Mock,那就不会存在垃圾数据的问题,也不用担心环境切换带来的问题,外部耗时的操作也可以通过Mock避免CI过程过长。

个人认为Mock只是模拟调用外部的行为,并不影响代码逻辑。所以,不存在“Mock是不是有效的单元测试”这种说法。

如何Mock?

应该Mock什么?

通常,我们编写的方法(或函数)都是由很多方法按照层级组成的,就像这样

当我们对顶层方法进行单元测试时,应该Mock哪些方法?

  • 如果Mock方法1、2、3,那么方法4、5、6就不会被调用到,里面的逻辑不会被覆盖到,也就不是有效的单元测试。
  • 如果Mock方法4、5、6,里面的逻辑或返回值有修改,那么就要递归向上修改,不符合软件工程。

但是,如果方法43、、5、6都涉及到DB或者网络调用等外部不可控操作,我们就应该对其Mock。

所以,应该Mock一些稳定的、不可控的方法。

Mock 编写示例

以Python中的Mock框架为例,下面是一个示例:

class TestXxService(unittest.TestCase):
    def test_init(self):
        XXService.update(xx)

class XXService:
    def update(xx):
        ......

test_init函数中的....update会涉及到数据库的操作,这里使用patch模拟这两个函数的行为

# patch("目标函数路径")
patch('....update')

在模拟的上下文中,XXService.update将会被模拟的函数替代执行

    def test_init(self):
        with patch('....update') as mocked_update:
            # 在模拟的上下文中调用业务逻辑函数
            XXService.update(xx)
            mocked_update.assert_called_once_with(xx)

其中,assert_called_once_with 会验证模拟函数是否被调用了一次,并且会验证预期接收的参数是否匹配。

如果没有参数,使用assert_called_once进行验证是否被调用了一次。

如果模拟的函数实际被调用了多次,需要通过以下方式

# 断言mocked_update被调用了2次
self.assertEqual(mocked_update.call_count, 2)
# 断言mocked_update被调用了,并且参数正确
mocked_update.assert_any_call(xx)

如果函数有返回值,在定义模拟函数时,添加 return_value,return_value可以是任意类型。

patch('...update',
                    return_value='xxx') as mocked_update

在验证返回值时通过下面的方式

xxxx = mocked_update.return_value
self.assertEqual(xxxx, 'xxx')

通过示例,我们Mock了XXService.update行为,实现了对XXService的隔离测试,并确保了测试的可靠性和高效性。

总结

单元测试中使用Mock有以下几个好处:

  1. 隔离测试:Mock 使得测试可以专注于测试的代码逻辑,而不必关心外部不稳定因素。
  2. 提高测试速度:Mock 可以避免耗时的外部调用,从而加快测试速度。
  3. 提高测试的可靠性和稳定性:通过Mock,可以避免外部变化对测试结果的影响。

标签:mocked,单元测试,update,调用,测试,Mock
From: https://blog.csdn.net/qq_28314431/article/details/140668925

相关文章

  • 【C++】单元测试覆盖率工具lcov的使用
    本文首发于❄️慕雪的寒舍本文讲述了如何在C++代码中使用单元测试覆盖率工具lcov,以及gcov命令的使用。版本是lcov2.0和gcov11.4.0。写在前面:lcov是我在实习期间初次接触到的工具,当时在配置的时候就遇到了大量中文互联网没有任何记录的问题。绝大部分博客对lcov工具的......
  • .NET 8 Moq mock GetRequiredKeyedService Setup报错yk
    .NET8MoqmockGetRequiredKeyedServiceSetup报错项目代码里有地方用到IServiceProvider.GetRequiredKeyedService来解析服务,在写单元测试时需要Mock它,本以为像下面这样写就可以了:||varserviceProvider=newMock<IServiceProvider>();||---|---|||serviceP......
  • .NET 8 Moq mock GetRequiredKeyedService Setup报错Hz
    .NET8MoqmockGetRequiredKeyedServiceSetup报错项目代码里有地方用到IServiceProvider.GetRequiredKeyedService来解析服务,在写单元测试时需要Mock它,本以为像下面这样写就可以了:||varserviceProvider=newMock<IServiceProvider>();||---|---|||serviceP......
  • Mockito用法总结
    Mockito的是用来做什么的Mockito主要用于单元测试过程中模拟被调用方法的依赖<dependency><groupId>org.mockito</groupId><artifactId>mockito-core</artifactId><version>4.8.0</version><scope>test</scope></depende......
  • .NET 8 Moq mock GetRequiredKeyedService Setup报错b9
    .NET8MoqmockGetRequiredKeyedServiceSetup报错项目代码里有地方用到IServiceProvider.GetRequiredKeyedService来解析服务,在写单元测试时需要Mock它,本以为像下面这样写就可以了:||varserviceProvider=newMock<IServiceProvider>();||---|---|||serviceP......
  • .NET 8 Moq mock GetRequiredKeyedService Setup报错
    .NET8MoqmockGetRequiredKeyedServiceSetup报错项目代码里有地方用到IServiceProvider.GetRequiredKeyedService<T>来解析服务,在写单元测试时需要Mock它,本以为像下面这样写就可以了:varserviceProvider=newMock<IServiceProvider>();serviceProvider.Setup(x=>x.GetR......
  • 微信开发者工具启用Mock模拟网络请求
    当开发微信小程序在后端接口还没开发好的情况下,想要进行接口调试怎么办?微信开发者工具提供了Mock功能,方便开发者模拟网络请求提前调试。1、在调试器中选Mock2、启用Mock3、新建规则API接口选择request(网络请求)类型参数规则匹配,填写正确的url正则匹配规则(包含参数)模......
  • 使用Python进行Mock测试详解(含Web API接口Mock)
    使用Python进行Mock测试详解(含WebAPI接口Mock)在软件开发过程中,单元测试是非常重要的一部分。为了确保代码的质量和可靠性,开发者需要编写测试用例来检查代码的行为是否符合预期。然而,在测试中有时会遇到一些难以直接测试的情况,例如依赖外部系统、数据库或网络服务等。在这......
  • Mockito教程(单测mock)
    1Mockito介绍[3]1.1Mockito是什么?Mockito是mocking框架,它让你用简洁的API做测试。而且Mockito简单易学,它可读性强和验证语法简洁。1.2为什么需要Mock测试驱动的开发(TDD)要求我们先写单元测试,再写实现代码。在写单元测试的过程中,我们往往会遇到要测试的类有很多依赖,这些......
  • 大白话单元测试之mock测试
    文章目录一、什么是Mock测试二、传统的单元测试JunitTest三、Mock测试(对比junit测试)四、Mock详解1.@InjectMocks和@Mock用法2.when用法3.verify用法五、Mock其他常用用法1.如何初始化数据2.初始化service类中的Apollo配置3.Assert.assertEquals用法一、什么是Mo......