Mock attributes in Python mock?
A compact and simple way to do it is to use new_callable
patch
's attribute to force patch
to use PropertyMock
instead of MagicMock
to create the mock object. The other arguments passed to patch
will be used to create PropertyMock
object.
with patch('requests.post.ok', new_callable=PropertyMock, return_value=True) as mock_post:
"""Your test"""
You need to use return_value
and 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 PropertyMock
for the property ok
to return the value True
.
With mock version '1.0.1' the simpler syntax mentioned in the question is supported and works as is!
Example code updated (py.test is used instead of 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)
$ 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 =================