#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
, что он работает аналогичным образом, но это имеет смысл