Исправление импортированных функций в приборе Pytest

#python #pytest #monkeypatching

#python #pytest #исправление ошибок

Вопрос:

У меня возникли проблемы с правильным исправлением импортированной функции в pytest. Функция, которую я хочу исправить, — это функция, предназначенная для выполнения большой выборки SQL, поэтому для ускорения я хотел бы заменить это чтением файла CSV. Вот код, который у меня есть в настоящее время:

 from data import postgres_fetch
import pytest

@pytest.fixture
def data_patch_market(monkeypatch):
    test_data_path = os.path.join(os.path.dirname(__file__), 'test_data')
    if os.path.exists(test_data_path):
        mock_data_path = os.path.join(test_data_path, 'test_data_market.csv')
        mock_data = pd.read_csv(mock_data_path)
        monkeypatch.setattr(postgres_fetch, 'get_data_for_market', mock_data)


def test_mase(data_patch_market):
    data = postgres_fetch.get_data_for_market(market_name=market,
                                              market_level=market_level,
                                              backtest_log_ids=log_ids,
                                              connection=conn)

    test_result= build_features.MASE(data)
 

Однако, когда я запускаю этот тест, я получаю сообщение об ошибке типа при вызове фрейма данных:

 TypeError: 'DataFrame' object is not callable
 

Я знаю, что csv можно прочитать правильно, поскольку я тестировал это отдельно, поэтому я предполагаю, что что-то не так с тем, как я реализую исправление, но, похоже, я не могу с этим разобраться

Ответ №1:

Здесь ваш вызов to monkeypatch.setattr заменяет любой вызов to postgres_fetch.get_data_for_market вызовом to mock_data .

Это не может работать, поскольку mock_data это не функция — это DataFrame объект.

Вместо этого при вызове monkeypatch.setattr вам нужно передать функцию, которая возвращает измененные данные (т. Е. DataFrame Объект).

Следовательно, что-то вроде этого должно работать:

 @pytest.fixture
def data_patch_market(monkeypatch):
    test_data_path = os.path.join(os.path.dirname(__file__), 'test_data')
    if os.path.exists(test_data_path):
        mock_data_path = os.path.join(test_data_path, 'test_data_market.csv')
        mock_data = pd.read_csv(mock_data_path)

        # The lines below are new - here, we define a function that will return the data we have mocked
        def return_mocked(*args, **kwargs):
            return mock_data
        monkeypatch.setattr(postgres_fetch, 'get_data_for_market', return_mocked)
 

Комментарии:

1. Отлично, спасибо! Раньше я использовал только unittest.mock декоратор, который напрямую указывает возвращаемое значение, поэтому у меня сложилось впечатление setattr , что он работает аналогичным образом, но это имеет смысл