Reputation: 321
I am using pytest
to test a method that calls requests.post
. Is there a easy way and preferably without third party libraries to do this?
class Dispatcher:
def __init__(self, url):
self.url = url
self.session = None
def dispatch(self):
return self.session.post(self.url).json()
def test_dispatch():
d = Dispatcher(url="")
d.session = # ... here, how can I mock the return value of json()?
result = d.dispatch()
Upvotes: 0
Views: 330
Reputation: 14216
So this is a pretty straightforward example. We want to set session
to be a MagicMock
object.
from unittest.mock import MagicMock
def test_dispatch():
expected = {"fizz": "buzz"}
mock_session = MagicMock()
mock_session.configure_mock(
**{
"post.return_value": mock_session,
"json.return_value": expected
}
)
d = Dispatcher(url="")
d.session = mock_session
result = d.dispatch()
assert result == expected
Since Mock
objects return a brand new mock object when methods are called on them (without being configured), we have to configure the object as such. If we didn't configure post
to return the original mock we have, then it would return a brand new mock object and our test would fail. Conversely you can configure another Mock
object to be the return value of post
and configure that object, but I prefer this approach.
Explanation showing the call is listed below.
self.session
is our mock_session
object we created
self.session.post(arg, **kwargs)
returns mock_session
mock_session.json()
returns the dictionary we specified
Upvotes: 1