Проблема с имитацией нескольких элементов в объекте пути - PullRequest
0 голосов
/ 27 мая 2020

У меня есть код, который выглядит следующим образом:

@patch.object(Path, "__init__", return_value=None)
@patch.object(Path, "exists", return_value=True)
@patch.object(Path, "read_text", return_value="FAKEFIELD: 'FAKEVALUE'")
def test_load_param_from_file_exists(self, *mock_path):
    expected_dict = YAML.safe_load("FAKEFIELD: 'FAKEVALUE'")
    return_dict = load_parameters("input", None)
    self.assertTrue(return_dict["FAKEFIELD"] == expected_dict["FAKEFIELD"])

и глубоко в коде load_parameters код выглядит следующим образом:

file_path = Path(parameters_file_path)
if file_path.exists():
    file_contents = file_path.read_text()
    return YAML.safe_load(file_contents)

Прямо сейчас я придется разбить его на два теста, потому что я не могу получить ни одного фиктивного объекта, который позволяет мне переключаться между «файл существует» и «файл не существует». В идеале я мог бы провести один тест вроде этого:

@patch.object(Path, "__init__", return_value=None)
@patch.object(Path, "exists", return_value=False)
@patch.object(Path, "read_text", return_value="FAKEFIELD: 'FAKEVALUE'")
def test_load_param_from_file(self, mock_path, *mock_path_other):
    with self.assertRaises(ValueError):
        load_parameters("input", False)

    mock_path.read_text.return_value = "FAKEFIELD: 'FAKEVALUE'"
    expected_dict = YAML.safe_load("FAKEFIELD: 'FAKEVALUE'")

    return_dict = load_parameters("input", None)

    self.assertTrue(return_dict["FAKEFIELD"] == expected_dict["FAKEFIELD"])

Чтобы было ясно, приведенное выше не работает, потому что каждый из этих исправленных объектов создается по-разному, и когда Path объект в методе load_parameters вызывается, exists имитируется правильно, но read_text не возвращает значения.

Что я делаю не так? Есть ли способ исправить несколько методов для одного объекта или класса?

1 Ответ

1 голос
/ 28 мая 2020

Я думаю, вы усложняете это, чем должно быть:

def test_load_param_from_file_exists(self):

    # Adjust the name as necessary
    mock_path = Mock()
    mock_path.exists.return_value = True
    mock_path.read_text.return_value = '{"FAKEFIELD": "FAKEVALUE"}'

    with patch("Path", return_value=mock_path):
        return_dict = load_parameters("input", None)

    self.assertTrue(return_dict["FAKEFIELD"] == 'FAKEVALUE')

Настройте Mock, чтобы он вел себя так, как вы хотите file_path, затем исправьте Path, чтобы вернуть это при его вызове.

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

...