Издевательство над глобальной функцией в Python

#python #mocking #global

Вопрос:

У меня есть (упрощенный) скрипт, подобный этому, который открывает файл в глобальной настройке. Однако этот файл отсутствует в репозитории (добавляется только во время развертывания).

 # func.py import pickle  f = open("model.pkl", "r") model = pickle.load(f)  def function_a():  # do something  return 1  

Это тестовый сценарий. Очевидно, что в нем будет ошибка, так как model.pkl файла нет. Этот msg показан FileNotFoundError: [Errno 2] No such file or directory: 'model.pkl' .

 # test_func.py from func import function_a  def test_function_a():  ret = function_a()  assert 1 == ret  

Я попытался издеваться над функциями, чтобы открыть файл, но в том же файле отсутствует ошибка.

 # test_func.py from unittest.mock import patch  @patch("func.open") @patch("func.pickle.load") def test_function_a(mock_pickle, mock_open):  from func import function_a  ret = function_a()  assert 1 == ret  

Я знаю два способа преодолеть это.

  1. Воспользуйся if "pytest" not in sys.modules:
 import pickle import sys  if "pytest" not in sys.modules:  f = open("model.pkl", "r")  model = pickle.load(f)  def function_a():  # do something  return 1  
  1. Поместите глобальный файл, вызывающий под if __name__ == "__main__"
 import pickle import sys  def function_a():  # do something  return 1  if __name__ == "__main__":  f = open("model.pkl", "r")  model = pickle.load(f)  

Тем не менее, я хочу знать, могу ли я все еще издеваться над ними в тестовом сценарии, так как это самое элегантное решение без изменения существующего сценария.

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

1. Почему бы вам не добавить if os.path.isfile("model.pkl") предложение в основной сценарий, чтобы загрузка рассола происходила только тогда, когда файл существует. Это только делает ваш скрипт более надежным, который можно импортировать, даже если файл существует. Другой вариант-создать фиктивный файл рассола с помощью тестового сценария. Поскольку текущий сценарий не может быть импортирован, если файл не существует, я не думаю, что это проблема насмешек или исправлений.