6

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?

Xar
  • 7,572
  • 19
  • 56
  • 80
  • 1
    Refer: https://stackoverflow.com/questions/12523189/how-to-mock-nested-functions – swapna p Sep 13 '19 at 13:07
  • This article explains why your mocking is not working https://nedbatchelder.com/blog/201908/why_your_mock_doesnt_work.html – Jacob Joy Feb 22 '23 at 11:00

2 Answers2

8

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)
Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
7

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

slackmart
  • 4,754
  • 3
  • 25
  • 39