一、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']

python mock总结

一、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。

  1. name
# name 是这个Mock实例的唯一标识 ,id是什么?内存,还是实例的编号?
>>> a = mock.Mock(name='name_1')
>>> print a
<Mock name='name_1' id='139821809679056'>
  1. 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
  1. 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实现的例子


  1. 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()
  1. 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

分类:

技术点:

相关文章: