Digamos que tengo esta función

from datetime import date

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

Luego tengo una tarea de apio para llamar a esta función sin pasar el base_date

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

En la prueba unitaria, estoy ejecutando la tarea refresh_settlement_date(), pero no proporciona el base_date cuando llama al get_next_friday(), mi pregunta es cómo burlarse de ese parámetro para probar los días en el futuro.

Estoy tratando de evitar agregar el parámetro para que se convierta en refresh_settlement_date(base_date) ya que no sirve para un propósito real sino solo para unittest.

1
James Lin 5 sep. 2014 a las 05:38

3 respuestas

La mejor respuesta

Debe @patch get_next_friday() funcionar y sustituir Es el valor de retorno con el que necesita:

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
1
alecxe 5 sep. 2014 a las 01:54

Acabo de probar esto, parece funcionar:

Primero necesito copiar la función:

old_get_next_friday = get_next_friday

Luego parchearlo:

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()
1
James Lin 5 sep. 2014 a las 01:54

Un enfoque alternativo sería parchear la fecha actual.

Hay un hilo relevante con múltiples opciones:


Mi opción favorita es usar un módulo de terceros llamado freezegun.

Necesitaría solo una línea para agregar, muy limpia y legible:

@freeze_time("2014-10-14")
def test_refresh_settlement_date_in_the_future(self):
    ...
3
Community 23 may. 2017 a las 11:56