一、Mock模块
为什么使用mock:
在我看来实际中用到mock的场景:
- 有个函数,我们不关心他的具体实现细节,只想要他的返回。这时就可以mock这个函数的返回
- mock对象来模拟一个需要使用的资源(?)
>>> import mock
>>> dir(mock.Mock())
['assert_any_call', 'assert_called', 'assert_called_once', 'assert_called_once_with', 'assert_called_with', 'assert_has_calls', 'assert_not_called', 'attach_mock', 'call_args', 'call_args_list', 'call_count', 'called', 'configure_mock', 'method_calls', 'mock_add_spec', 'mock_calls', 'reset_mock', 'return_value', 'side_effect']
一、Mock的构造器
init是mock对象的构造器,name是mock对象的唯一标识;spec设置的是mock对象的属性,可以是property或者方法,也可以是其他的列表字符串或者其他的python类;return_value设置的是,当这个mock对象被调用的时候,显示出的结果就是return_value的值;side_effect是和return_value是相反的,覆盖了return_value,也就是说当这个mock对象被调用的时候,返回的是side_effect的值,而不是return_value。
- name
# name 是这个Mock实例的唯一标识 ,id是什么?内存,还是实例的编号?
>>> a = mock.Mock(name='name_1')
>>> print a
<Mock name='name_1' id='139821809679056'>
- return_value
(a)、return_value指定的是某个值
# 这个b可以是函数名(add),类的函数名(Person.add)
# b应该是类的实例,可是b()返回 return_value,这个是怎么实现的?
>>> b = mock.Mock(name='name_3', return_value=100)
>>> b
<Mock name='name_3' id='139821809217744'>
>>> print b()
100
>>> print type(b)
<class 'mock.mock.Mock'>
(b)、return_value指定的是类的实例
import unittest
import mock
class Person():
arg_0 =5
def __init__(self):
self.arg_1 = 10
pass
def add(self):
return 20
p = Person()
mock_obj = mock.Mock(return_value=p)
a = mock_obj()
# mock_obj = mock.Mock() 只是返回一个mock实例
# 要他的返回值时a = mock_obj (),a就是return_value
print 'a: ',a
>>>a: <__main__.Person instance at 0xd46a28>
print 'a.add: ',a.add
>>>a.add: <bound method Person.add of <__main__.Person instance at 0xd46a28>>
print 'a.add(): ',a.add()
>>>a.add(): 20
print 'a.arg_1: ',a.arg_1
>>>a.arg_1: 10
print a.arg_0
>>>5
- side_effect参数:
(a)、指定的参数的值是异常
# 返回的异常覆盖了return_value
>>> import mock
>>> import unittest
>>> mock_object = mock.Mock(return_value=10, side_effect=StandardError)
>>> b = mock_object()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/site-packages/mock/mock.py", line 1062, in __call__
return _mock_self._mock_call(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/mock/mock.py", line 1118, in _mock_call
raise effect
StandardError
(b)、指定的参数的值是一个list或者tuple:
这个就不展开写了,目前我还没用到
二、Mock实现的例子
- Mock一个函数。
根据上面理解的Mock,可以这么实现:
import unittest
import mock
def multiple(a, b):
return a*b
class TestProducer(unittest.TestCase):
def setUp(self):
pass
def test_multiple(self):
multiple = mock.Mock(return_value=3)
self.assertEqual(multiple(8, 14), 3)
if __name__ == "__main__":
unittest.main()
另一种方法就是mock.patch
# 为啥执行报错???
# TypeError: Need a valid target to patch. You supplied: 'multiple'
#
import unittest
import mock
class Calculator(object):
def add(self, a, b):
return a+b
def multiple(a, b):
return a*b
class TestProducer(unittest.TestCase):
def setUp(self):
self.calculator = Calculator()
# mock.patch('multiple')一定
# mock_multiple 是不是可以随便命名???
@mock.patch('multiple')
def test_multiple(self, mock_multiple):
mock_multiple.return_value = 3
self.assertEqual(multiple(8, 14), 3)
if __name__ == "__main__":
unittest.main()
- Mock一个对象里面的方法
待续
三、
参考:
https://blog.csdn.net/peiyao456/article/details/77075173
https://blog.csdn.net/younger_china/article/details/72904448
https://www.cnblogs.com/yoyoketang/p/9346660.html