Как я могу использовать mock для возврата None для разбора известных аргументов? - PullRequest
0 голосов
/ 21 марта 2019

Ниже у меня есть функция, которая возвращает две даты на основе ввода в командной строке.Как я могу использовать mock, чтобы сделать так, чтобы я мог выполнять модульное тестирование в операторе else?

# time from of pull
def time_frame():
    """
    checks for optional user input for start and end date of data pull
    creates start and end date for query
    :return: start and end date
    """
    # get the dates
    args, leftovers = get_the_args()

    if args.start_dt is not None and args.end_dt is not None:

        return args.start_dt, args.end_dt

    else:

        # get today
        the_today_start_date, the_today_end_date = get_dates_from_today()

        return the_today_start_date, the_today_end_date

Я пытался с помощью mock_get_the_args.return_value = mock.Mock(return_value=None), mock.Mock() сделать так, чтобы вывод args функции get_the_args() возвращал None при выполнении этого раздела моего модульного теста?Что мне нужно, чтобы изменить мой mock.Mock (), который представляет переменную args, чтобы это работало?

Ниже приведен модульный тест:

# the time frame
@mock.patch('src.toolkit.get_dates_from_today')
@mock.patch('src.toolkit.get_the_args')
def test_time_frame(mock_get_the_args, mock_get_dates_from_today):
    # set some dates
    start_date = '2019-01-01'
    end_date = '2019-01-01'
    # mocking
    mock_get_the_args.return_value = mock.Mock(), mock.Mock()
    mock_get_dates_from_today.return_value = mock.Mock(), mock.Mock()

    start_date, end_date = time_frame() 
    mock_get_the_args.assert_called_once()

    mock_get_the_args.return_value = mock.Mock(return_value=None), mock.Mock()
    start_date, end_date = time_frame() 
    mock_get_dates_from_today.assert_called_once()

1 Ответ

1 голос
/ 21 марта 2019

Модульное тестирование с кодом argparse немного сложнее, поскольку обычно ожидает ввода из командной строки. Но само тестирование использует командную строку (возможно, с собственным анализатором argparse).

Я полагаю, get_the_args устанавливает парсер и возвращает parser.parse_known_args().

В целях тестирования удобно предоставить себе возможность предоставления явного списка argv.

например:.

def time_frame(argv=None):
    """
    checks for optional user input for start and end date of data pull
    creates start and end date for query
    :return: start and end date
    """
    # get the dates
    args, leftovers = get_the_args(argv)
    ...

, где get_the_args использует parse_known_args(argv).

Если argv - None, то он анализирует обычную командную строку. Но вы можете предоставить любой список строк, который генерирует нужные args и extras. По сути, вы можете имитировать командную строку.

Другим вариантом является определение args объекта пространства имен, например. args = argparse.Namespace(start_dt=None, end_dt='foobar'). Тогда вы можете использовать args.start_dt, как и раньше.

Еще одна вещь, облегчающая тестирование, - это запуск parser только тогда, когда код запускается как скрипт, а не когда он импортируется. То есть поместите его в `if name == ' main ': block.

...