Reputation: 7910
I'm trying to use Mock
to test the result returned from a function that retrieves a setting:
def apply_delta_to_date(original_date):
delta = MySettings.get_delta()
result_date = original_date + timedelta(delta)
return result_date
When testing the apply_delta_to_date
function, I'm trying to mock the call to MySettings.get_delta
to simulate that its returning a specific result:
class TestAppyDelta():
def setUp(self):
self.MySettings = Mock()
self.MySettings.get_delta = Mock(return_value=10)
def test_apply_delta(self):
result = apply_delta_to_date(today)
The problem is that I can't manage to "mock" the function call to MySettings.get_delta()
which is inside the function that I really want to test.
How could I mock the result returned by an inner function inside the function I'm testing?
Upvotes: 11
Views: 27272
Reputation: 4924
What you need is the patch.object context manager, which does exactly what you want: it takes a class and method, and allows you to define a custom return value.
from unittest.mock import patch
from <your-time_utils-module> import apply_delta_to_date, MySettings
class TestAppyDelta():
def test_apply_delta(self):
with patch.object(MySettings, 'get_delta', return_value=10) as mock_method:
result = apply_delta_to_date(today)
# mock_method has many other useful assertions
mock_method.assert_called_once()
Refer to the docs for more details https://docs.python.org/3/library/unittest.mock.html#quick-guide
Upvotes: 9
Reputation: 599490
You're not mocking the right thing at all. All you have done is to define a MySettings attribute in your test class. It is never called by anything.
You need to mock the reference to MySettings in the place where it is called. Assuming you're importing apply_delta_to_date
from a module called my_delta_module
:
@patch('my_delta_module.MySettings')
def test_apply_delta(self, mock_settings):
mock_settings.get_delta.return_value = 10
result = apply_delta_to_date(today)
Upvotes: 11