Python单元测试之mock使用

什么是mock?比如当我们需要用一个接口时,这个接口还没有实现或者依赖第三方服务,为了保证当前功能的开发和测试,就需要使用mock模拟这些接口。

Python中使用mock对象替代掉指定的Python对象,实现控制Python对象的行为。mock模块在Python 3.3以后合并到unittest模块中了,可以直接通过导入使用。

Mock基本使用

Mock对象就是mock模块中的一个类的实例,能在整个测试套件中模拟大量的方法。创建后,就可以指定返回值并设置所需的属性,也可以断言调用了哪些方法/属性及其参数。

class Mock(spec=None, side_effect=None, return_value=DEFAULT, wraps=None, name=None, spec_set=None, **kwargs)

Mock类主要的几个参数:

  • name:命名一个mock对象,只是起到标识作用,可以通过print查看。
  • return_value: 定义mock方法的返回值,可以指定一个值(或者对象),当mock对象被调用时,返回return_value指定的值。
  • side_effect: 这个参数指向一个可调用对象,接收一个可迭代序列。可以抛出异常或者动态改变值。当传递这个参数的时候return_value 参数就会失效。
  1. from unittest import mock

  2. result1 = mock.Mock(name='mock名称')

  3. print(result1)

  4. mock_value1 = mock.Mock(return_value="返回值1")

  5. print(mock_value1())

  6. mock_value2 = mock.Mock(return_value="返回值2",side_effect= [1,2,3])

  7. print(mock_value2())

  8. print(mock_value2())

  9. print(mock_value2())

Mock 步骤如下:
  • 导入 unittest 框架中的 mock
  • 找到要替换的对象A,可以是一个类、函数或者类实例
  • 实例化mock对象,设置mock对象的行为,比如调用的时候返回的值,被访问成员的时候返回什么值等。
  • 使用mock对象替换对象A
  • 调用并断言
mock一个未开发的接口

 

mock一个依赖关系的功能

实际工作中,我们也会遇到这样的场景,测试A模块,然后A模块依赖于B模块的调用,这时就可以借助mock在单元测试中分别测试正常返回和异常返回的情况。

访问baidu的功能,visit_baidu()方法依赖send_request的返回结果。

  1. import requests

  2. def send_request(url):

  3. r = requests.get(url)

  4. return r.status_code

  5. def visit_baidu():

  6. url = 'http://www.baidu.com'

  7. return send_request(url)

用mock对象在单元测试中分别测试正常返回和异常返回的情况

  1. from unittest import mock

  2. import unittest

  3. import demo

  4. class TestReq(unittest.TestCase):

  5. def test_request_01(self):

  6. # 实例化mock对象,指定返回值,替换原有对象

  7. demo.send_request = mock.Mock(return_value='200')

  8. print(demo.send_request())

  9. self.assertEqual(demo.visit_baidu(), '200')

  10. def test_request_02(self):

  11. # 实例化mock对象,指定返回值,替换原有对象

  12. demo.send_request = mock.Mock(return_value='404')

  13. print(demo.send_request())

  14. self.assertEqual(demo.visit_baidu(), '404')

  15. if __name__ == '__main__':

  16. unittest.main(verbosity=2)

 

Mock的高级用法

mock库提供了patch函数来简化mock对象对原对象的替换,该函数会返回一个mock内部的类实例,它可以控制mock的范围,可以作为装饰器或者上下文管理器使用。

mock.patch(target,new = DEFAULT,spec = None,create = False,spec_set = None,autospec = None,new_callable = None,** kwargs )

mock装饰器使用格式

  • @patch("module名字.方法名")
  • @patch.object(类名, "方法名")

patch作为装饰器,需要把你想模拟的函数写在里面,然后在后面的单元测试案例中为它赋一个具体实例,再用return_value 来指定模拟函数返回的结果。

改造上面的单元测试:

  1. from unittest import mock

  2. import unittest

  3. import demo

  4. class TestReq(unittest.TestCase):

  5. #在测试的参数里对该Mock对象设置一个参数

  6. @mock.patch("demo.send_request")

  7. def test_request_01(self,mock_request):

  8. # 指定一个返回值

  9. mock_request.return_value='200'

  10. self.assertEqual(demo.visit_baidu(), '200')

  11. @mock.patch("demo.send_request")

  12. def test_request_02(self,mock_request):

  13. # 指定一个返回值

  14. mock_request.return_value='404'

  15. self.assertEqual(demo.visit_baidu(), '404')

  16. if __name__ == '__main__':

  17. unittest.main(verbosity=2)

总结:

感谢每一个认真阅读我文章的人!!!

作为一位过来人也是希望大家少走一些弯路,如果你不想再体验一次学习时找不到资料,没人解答问题,坚持几天便放弃的感受的话,在这里我给大家分享一些自动化测试的学习资源,希望能给你前进的路上带来帮助。

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

 

          视频文档获取方式:
这份文档和视频资料,对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!以上均可以分享,点下方小卡片即可自行领取。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值