3

Lets say I have this function

from datetime import date

def get_next_friday(base_date=date.today()):
   next_friday = ...
   return next_friday

Then I have a celery task to call this function without passing in the base_date

@celery_app.task
def refresh_settlement_date():
   Record.objects.update(process_date=get_next_friday())

In the unittest I am running the refresh_settlement_date() task, but it's not providing the base_date when it's calling the get_next_friday(), my question is how to mock that parameter to test the days in the future?

I am trying to avoid adding parameter to become refresh_settlement_date(base_date) as it doesn't serve real purpose but only for unittest.

UmNyobe
  • 22,539
  • 9
  • 61
  • 90
James Lin
  • 25,028
  • 36
  • 133
  • 233

3 Answers3

4

An alternative approach would to be to patch the current date.

There is a relevant thread with multiple options:


My favorite option is to use a third-party module called freezegun.

You would need only one line to add, very clean and readable:

@freeze_time("2014-10-14")
def test_refresh_settlement_date_in_the_future(self):
    ...
Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
1

You need to @patch get_next_friday() function and substitute it's return value with the one you need:

date_in_the_future = date.today() + timedelta(50)
next_friday_in_the_future = get_next_friday(base_date=date_in_the_future)

with patch('module_under_test.get_next_friday') as mocked_function:
    mocked_function.return_value = next_friday_in_the_future

    # call refresh_settlement_date
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
1

I just tried this out, it seems to work:

first I need to copy the function:

old_get_next_friday = get_next_friday

then patch it:

with patch.object(get_next_friday) as mocked_func:
    for i in range(8):
        mocked_func.return_value = old_get_next_friday(date.today() + timedelta(days=i))
        refresh_settlement_date()
James Lin
  • 25,028
  • 36
  • 133
  • 233