Xar
Xar

Reputation: 7910

Python Mock: Mocking a function inside the function I'm testing

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

Answers (2)

slackmart
slackmart

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

Daniel Roseman
Daniel Roseman

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

Related Questions