Python模拟中的模拟属性?
我在Python中使用Python模拟中的模拟属性?,python,unit-testing,testing,mocking,python-mock,Python,Unit Testing,Testing,Mocking,Python Mock,我在Python中使用mock时遇到了相当大的困难: 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(
mock
时遇到了相当大的困难:
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.")
def method_under_test():
r=请求。post(“http://localhost/post")
打印r.ok#打印“”
如果r.ok:
返回StartResult()
其他:
引发异常()
类MethodUnderTestTest(TestCase):
def测试下的def测试方法(自):
将补丁('requests.post')作为补丁发布:
已修补的\u post.return\u value.ok=True
结果=试验()下的方法
self.assertEqual(类型(结果)、StartResult、,
“未能返回StartResult。”)
测试实际上返回正确的值,但是r.ok
是模拟对象,而不是True
。如何在Python的mock
库中模拟属性?您需要使用和:
这意味着:在调用
请求时。post
,在该调用的返回值上,为属性ok
设置PropertyMock
,以返回值True使用模拟版本“1.0.1”,问题中提到的更简单语法将得到支持并按原样工作
示例代码更新(使用py.test代替unittest):
运行以下代码:(确保安装了pytest)
一种紧凑而简单的方法是使用new\u callable
patch
的属性强制patch
使用PropertyMock
而不是MagicMock
来创建模拟对象。传递给patch
的其他参数将用于创建PropertyMock
对象
with patch('requests.post.ok', new_callable=PropertyMock, return_value=True) as mock_post:
"""Your test"""
如果我在测试下的方法中打印r.ok
的值,我看到
,而不是True
@TKKocheran:我已经更新了我的答案。您还需要使用PropertyMock
。为什么不简单地使用patched\u post.return\u value=mock.mock(ok=True)
?@lumbric,因为您可以使用PropertyMock
来声明它与任何其他mock
对象一样被访问。仅仅给属性赋值是做不到的。这并不能回答这个问题。若要评论或要求作者澄清,请在其帖子下方留下评论-您可以随时对自己的帖子发表评论,一旦您有足够的评论,您就可以发表评论。仅供参考请求。post.ok
是一个属性,而不是一个属性。如果您尝试使用简单对象,其中ok
是一个简单属性,则问题中提到的语法适用于请求。post.ok
对象否:它将引发AttributeError
@philant感谢您的反馈,正如示例所证明的,这是问题的最新答案,语法恰好简单得多。@Micheled'Amico感谢您的反馈,我试过了,请看一看;-)
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"
$ 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 =================
with patch('requests.post.ok', new_callable=PropertyMock, return_value=True) as mock_post:
"""Your test"""