Python 模拟中的模拟属性?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16867509/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mock attributes in Python mock?
提问by Naftuli Kay
I'm having a fairly difficult time using mockin Python:
我mock在 Python 中使用起来相当困难:
def method_under_test():
r = requests.post("http://localhost/post")
print r.ok # prints "<MagicMock name='post().ok' id='11111111'>"
if r.ok:
return StartResult()
else:
raise Exception()
class MethodUnderTestTest(TestCase):
def test_method_under_test(self):
with patch('requests.post') as patched_post:
patched_post.return_value.ok = True
result = method_under_test()
self.assertEqual(type(result), StartResult,
"Failed to return a StartResult.")
The test actually returns the right value, but r.okis a Mock object, not True. How do you mock attributes in Python's mocklibrary?
测试实际上返回了正确的值,但它r.ok是一个 Mock 对象,而不是True. 你如何模拟 Pythonmock库中的属性?
采纳答案by Simeon Visser
You need to use return_valueand PropertyMock:
您需要使用return_value和PropertyMock:
with patch('requests.post') as patched_post:
type(patched_post.return_value).ok = PropertyMock(return_value=True)
This means: when calling requests.post, on the return value of that call, set a PropertyMockfor the property okto return the value True.
这意味着:在调用 时requests.post,在该调用的返回值上,PropertyMock为属性设置一个ok以返回值True。
回答by howaryoo
With mock version '1.0.1' the simpler syntax mentioned in the question is supported and works as is!
使用模拟版本“1.0.1”,支持问题中提到的更简单的语法并按原样工作!
Example code updated (py.test is used instead of unittest):
示例代码更新(使用 py.test 代替 unittest):
import mock
import requests
def method_under_test():
r = requests.post("http://localhost/post")
print r.ok
if r.ok:
return r.ok
else:
raise Exception()
def test_method_under_test():
with mock.patch('requests.post') as patched_post:
patched_post.return_value.ok = True
result = method_under_test()
assert result is True, "mock ok failed"
Run this code with: (make sure you install pytest)
使用以下代码运行此代码:(确保安装 pytest)
$ py.test -s -v mock_attributes.py
======= test session starts =======================
platform linux2 -- Python 2.7.10 -- py-1.4.30 -- pytest-2.7.2 -- /home/developer/miniconda/bin/python
rootdir: /home/developer/projects/learn/scripts/misc, inifile:
plugins: httpbin, cov
collected 1 items
mock_attributes.py::test_method_under_test True
PASSED
======= 1 passed in 0.03 seconds =================
回答by Michele d'Amico
A compact and simple way to do it is to use new_callablepatch's attribute to force patchto use PropertyMockinstead of MagicMockto create the mock object. The other arguments passed to patchwill be used to create PropertyMockobject.
一种紧凑而简单的方法是使用new_callablepatch的属性来强制patch使用PropertyMock而不是MagicMock创建模拟对象。传递给的其他参数patch将用于创建PropertyMock对象。
with patch('requests.post', new_callable=PropertyMock, return_value=True) as mock_post:
"""Your test"""

