python mock接口怎么用_python接口自动化测试 - mock模块基本使用介绍

mock简介

py3已将mock集成到unittest库中

为的就是更好的进行单元测试

简单理解,模拟接口返回参数

通俗易懂,直接修改接口返回参数的值

mock作用

解决依赖问题,达到解耦作用

当我们测试某个目标接口(模块)时,该接口依赖其他接口,当被依赖的接口未开发完成时,可以用mock模拟被依赖接口,完成目标接口的测试

模拟复杂业务的接口

当我们测试某个目标接口(模块),该接口依赖一个非常复杂的接口时,可以用mock来模拟这个复杂的业务接口;也解决接口依赖一样的原理

单元测试

如果某个接口(模块)未开发完成时,又需要编写测试用例,则可以通过mock模拟该接口(模块)进行测试

前后端联调

前端开发的页面需要根据后端返回的不同状态码展示不同的页面,当后端接口未开发完成时,也可通过mock来模拟后端接口返回自己想要的数据

mock类解读

class Mock(spec=None,side_effect=None,return_value=DEFFAULT,name=None)

secp:定义mock对象的属性值,可以是列表,字符串,甚至一个对象或者实例

side_effect:可以用来抛出异常或者动态改变返回值,它必须是一个iterator(列表),它会覆盖return_value

return_value:定义mock方法的返回值,它可以是一个值,可以是一个对象(如果存在side_effect参数那这个就没有用,也就是不能同时用)

name:作为mock对象的一个标识,在print时可以看到

mock实际使用

一个未开发完成的功能如何测试?

1 defadd(self, a, b):2 """两个数相加"""

3 pass

4

5

6 classTestSub(unittest.TestCase):7 """测试两个数相加用例"""

8

9 deftest_sub(self):10 #创建一个mock对象 return_value代表mock一个数据

11 mock_add = mock.Mock(return_value=15)12 #将mock对象赋予给被测函数

13 add =mock_add14 #调用被测函数

15 result = add(5, 5)16 #断言实际结果和预期结果

17 self.assertEqual(result, 15)

一个完成开发的功能如何测试?

1 classSubClass(object):2 defadd(self, a, b):3 """两个数相加"""

4 return a +b5

6 classTestSub(unittest.TestCase):7 """测试两个数相加用例"""

8

9 deftest_add2(self):10 #初始化被测函数类实例

11 sub =SubClass()12 #创建一个mock对象 return_value代表mock一个数据

13 #传递side_effect关键字参数, 会覆盖return_value参数值, 使用真实的add方法测试

14 sub.add = mock.Mock(return_value=15, side_effect=sub.add)15 #调用被测函数

16 result = sub.add(5, 5)17 #断言实际结果和预期结果18 self.assertEqual(result, 10)

side_effect:这里给的参数值是sub.add相当于add方法的地址,当我们调用add方法时就会调用真实的add方法

简单理解成:传递了side_effect参数且值为被测函数地址时,mock不会起作用;两者不可共存

另外,side_effect接受的是一个可迭代序列,当传递多个值时,每次调用mock时会返回不同的值;如下

1 mock_obj = mock.Mock(side_effect= [1,2,3])2 print(mock_obj())3 print(mock_obj())4 print(mock_obj())5 print(mock_obj())6

7 #输出

8 Traceback (most recent call last):9 1

10 File "D:/MyThreading/mymock.py", line 37, in

11 2

12 print(mock_obj())13 3

14 File "C:\Python36\lib\unittest\mock.py", line 939, in __call__

15 return _mock_self._mock_call(*args, **kwargs)16 File "C:\Python36\lib\unittest\mock.py", line 998, in_mock_call17 result =next(effect)18 StopIteration

存在依赖关系的功能如何测试?

1 #支付类

2 classPayment:3

4 defrequestOutofSystem(self, card_num, amount):5 ‘‘‘

6 请求第三方外部支付接口,并返回响应码7 :param card_num: 卡号8 :param amount: 支付金额9 :return: 返回状态码,200 代表支付成功,500 代表支付异常失败10 ‘‘‘

11 #第三方支付接口请求地址(故意写错)

12 url = "http://third.payment.pay/"

13 #请求参数

14 data = {"card_num": card_num, "amount": amount}15 response = requests.post(url, data=data)16 #返回状态码

17 returnresponse.status_code18

19 defdoPay(self, user_id, card_num, amount):20 ‘‘‘

21 支付22 :param userId: 用户ID23 :param card_num: 卡号24 :param amount: 支付金额25 :return:26 ‘‘‘

27 try:28 #调用第三方支付接口请求进行真实扣款

29 resp =self.requestOutofSystem(card_num, amount)30 print(‘调用第三方支付接口返回结果:‘, resp)31 exceptTimeoutError:32 #如果超时就重新调用一次

33 print(‘重试一次‘)34 resp =self.requestOutofSystem(card_num, amount)35

36 if resp == 200:37 #返回第三方支付成功,则进行系统里面的扣款并记录支付记录等操作

38 print("{0}支付{1}成功!!!进行扣款并记录支付记录".format(user_id, amount))39 return ‘success‘

40

41 elif resp == 500:42 #返回第三方支付失败,则不进行扣款

43 print("{0}支付{1}失败!!不进行扣款!!!".format(user_id, amount))44 return ‘fail‘

45

46 #单元测试类

47 classpayTest(unittest.TestCase):48

49 deftest_pay_success(self):50 pay =Payment()51 #模拟第三方支付接口返回200

52 pay.requestOutofSystem = mock.Mock(return_value=200)53 resp = pay.doPay(user_id=1, card_num=‘12345678‘, amount=100)54 self.assertEqual(‘success‘, resp)55

56 deftest_pay_fail(self):57 pay =Payment()58 #模拟第三方支付接口返回500

59 pay.requestOutofSystem = mock.Mock(return_value=500)60 resp = pay.doPay(user_id=1, card_num=‘12345678‘, amount=100)61 self.assertEqual(‘fail‘, resp)62

63 deftest_pay_time_success(self):64 pay =Payment()65 #模拟第三方支付接口首次支付超时,重试第二次成功

66 pay.requestOutofSystem = mock.Mock(side_effect=[TimeoutError, 200])67 resp = pay.doPay(user_id=1, card_num=‘12345678‘, amount=100)68 self.assertEqual(‘success‘, resp)69

70 deftest_pay_time_fail(self):71 pay =Payment()72 #模拟第三方支付接口首次支付超时,重试第二次失败

73 pay.requestOutofSystem = mock.Mock(side_effect=[TimeoutError, 500])74 resp = pay.doPay(user_id=1, card_num=‘12345678‘, amount=100)75 self.assertEqual(‘fail‘, resp)

也许有小伙伴会问,第三方支付都不能用,我们的测试结果是否是有效的呢?

通常在测试一个模块的时候,是可以认为其他模块的功能是正常的,只针对目标模块进行测试是没有任何问题的,所以说测试结果也是正确的

mock装饰器

一共两种格式

@patch(‘module名字.方法名‘)

@patch.object(类名, ‘方法名‘)

1 #装饰类演示

2 from mock importMock, patch3

4

5 #单独的相乘函数

6 defmultiple(a, b):7 return a *b8

9

10 #单独的捕获Exception函数

11 defis_error():12 try:13 os.mkdir("11")14 returnFalse15 exceptException as e:16 returnTrue17

18

19 #计算类,包含add方法

20 classcalculator(object):21 defadd(self, a, b):22 return a +b23

24

25 #装饰类演示 - 单元测试类

26 classTestProducer(unittest.TestCase):27

28 #case执行前

29 defsetUp(self):30 self.calculator =calculator()31

32 #mock一个函数,注意也要指定module

33 @patch(‘mock_learn.multiple‘)34 deftest_multiple(self, mock_multiple):35 mock_multiple.return_value = 3

36 self.assertEqual(multiple(8, 14), 3)37

38 #mock一个类对象的方法

39 @patch.object(calculator, ‘add‘)40 deftest_add(self, mock_add):41 mock_add.return_value = 3

42 self.assertEqual(self.calculator.add(8, 14), 3)43

44 #mock调用方法返回多个不同的值

45 @patch.object(calculator, ‘add‘)46 deftest_effect(self, mock_add):47 mock_add.side_effect = [1, 2, 3]48 self.assertEqual(self.calculator.add(8, 14), 1)49 self.assertEqual(self.calculator.add(8, 14), 2)50 self.assertEqual(self.calculator.add(8, 14), 3)51

52 #mock的函数抛出Exception

53 @patch(‘os.mkdir‘)54 deftest_exception(self, mkdir):55 mkdir.side_effect =Exception56 self.assertEqual(is_error(), True)57

58 #mock多个函数,注意函数调用顺序

59 @patch.object(calculator, ‘add‘)60 @patch(‘mock_learn.multiple‘)61 deftest_more(self, mock_multiple, mock_add):62 mock_add.return_value = 1

63 mock_multiple.return_value = 4

64 self.assertEqual(self.calculator.add(3, 3), 1)65 self.assertEqual(multiple(3, 3), 4)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值