在Python中使用Mock()
你能给我一些关于在Django单元测试中使用Mock()的清晰例子吗?我想更清楚地理解它。
更新:我已经弄明白了一些事情,所以我在下面分享一下。
2 个回答
1
这个Mock网站有很不错的API文档,详细介绍了这些内容。需要注意的是,patch会替换掉所有地方调用的foo.Foo.foo
。虽然这不是模拟东西的最佳方法,但有时候可能是唯一的办法——可以参考open()。
21
第一部分:基础知识
from mock import Mock
模拟对象(Mock object)是一种特殊的对象,它就像是我们不想执行的代码的一个“替身”。但是我们希望从这个“替身”那里获取一些信息,比如被调用的次数和调用时传入的参数。此外,我们还可以为这些代码指定一个返回值。
让我们定义一个简单的函数:
def foo(value):
return value + value
现在我们准备为这个函数创建一个模拟对象:
mock_foo = Mock(foo, return_value='mock return value')
接下来我们可以检查一下:
>>> foo(1)
2
>>> mock_foo(1)
'mock return value'
并获取一些关于调用的信息:
>>> mock_foo.called
True
>>> mock_foo.call_count
1
>>> mock_foo.call_args
((1,), {})
Mock() 实例可用的属性有:
call_args func_code func_name
call_args_list func_defaults method_calls
call_count func_dict side_effect
called func_doc
func_closure func_globals
这些属性的意思都很明显。
第二部分:@patch
装饰器
@patch
装饰器让我们可以轻松地为导入的对象(类或方法)创建模拟对象。这在编写单元测试时非常有用。
假设我们有一个名为 foo.py
的模块:
class Foo(object):
def foo(value):
return value + value
现在我们来为 @patch
装饰器写一个测试。
我们将要对模块 foo
中的 Foo
类的 foo
方法进行补丁。别忘了导入相关内容。
from mock import patch
import foo
@patch('foo.Foo.foo')
def test(mock_foo):
# We assign return value to the mock object
mock_foo.return_value = 'mock return value'
f = foo.Foo()
return f.foo(1)
现在运行它:
>>> test()
'mock return value'
太好了!我们的方法成功被覆盖了。