def share(): """Share system generated message to weibo.""" msg = generate_msg() weibo = get_weibo_client(user_id) weibo.upload(msg)如果有一种方法,测试上面代码的时候能够运行所有的代码,但是并不实际执行weibo.upload(msg),而且还能知道每个函数被调用了几次,每次被调用的参数,那我们测试用例就方便多了。
>>> import os >>> def myremove(filename): >>> return filename >>> os.remove = myremove <function __main__.myremove> >>> print os.remove('test-file') test-file上面的例子是最简单的说明,如果把myremove修改成Mock类,然后这个类里面在调用的时候(复写 __call__)能够根据传进来的参数决定它的行为,还能记录每一次调用,你就大致了解 Mock 做了什么。
from mock import Mock myMethod = Mock() myMethod.return_value = 3 myMethod(1, 'a', foo='bar') myMethod.assert_called_with(1, 'a', foo='bar') # True myMethod() myMethod.call_count # 2想要mock出一个函数,直接使用mock.Mock()实例,你可以在初始化的时候设定返回值myMethod = Mock(return_value=3),也可以通过myMethod.return_value的属性来设置。
myMethod = Mock(side_effect=KeyError('whatever')) myMethod() Traceback (most recent call last): ... KeyError: 'whatever'上面的例子就是模拟一个异常,如果side_effect是函数的话,这个函数就会被调用,可以用来动态地生成返回值。下面的例子mock一个可以返回输入字符串长度的函数。
def side_effect(str): return len(str) myMethod = Mock(side_effect=side_effect) myMethod('sd') # 2在unittest的时候,mock还提供了下面几种assert语句:
assert_has_calls
(2)怎么 mock 一个类的方法?
要想mock一个类中的某个方法,可以使用mock提供的patch方法:import mock import Module1 @mock.patch.object(Module1.Class1, 'some_method') def test(mock_method): mock_method.return_value = 3 mock_method.side_effect = some_side_effect m = Module1.Class1() m.some_method(*args, **kwargs) assert m.some_method is mock_method m.some_method.assert_called_with(*args, **kwargs)
(3)怎么 mock 一个类?
有时候需要模拟一个函数或者类的行为,包括它所有的属性和方法,如果手动去一个个添加,实在低效而且容易出错。mock提供了autospec的功能,根据提供的模板类生成一个mock实例。 下面是mock一个函数的例子。import mock def myFunc(a, b, c): pass >>> mock_func = mock.create_autospec(myFunc, return_value=3) >>> mock_func(1,2,3) >>> mock_func.assert_called_with(1,2,3) >>> mock_func('a string') Traceback (most recent call last): ... TypeError: <lambda>() takes exactly 3 arguments (1 given)mock 一个类和这个相同:
>>> mock_class = mock.create_autospec(myClass)
(4)平时的用法
这里用返回值等于3,来模拟requests.post网络交互的返回值。省去了真实的网络交互。当然,也可以用一个方法返回值来取代3这个返回值。
import json import mock from django.test import TestCase class ApiTest(TestCase): @mock.patch('apps.agent.requests.post') def test(self, mock_method): mock_method.return_value = 3 mock_method.side_effect = some_side_effect res = self.client.post('/url/to/post') r = json.loads(res.content) self.assertEqual(0, r['retval'])
版权声明:本文为博主原创文章,未经博主允许不得转载。
python第三方库系列之十九--python测试使用的mock库
原文地址:http://blog.csdn.net/wenph2008/article/details/46862771