Ошибка в словаре mock.patch методов, вызываемых в списке - PullRequest
1 голос
/ 11 марта 2019

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

Есть ли что-то, чего мне здесь не хватает в моем понимании того, как работает насмешка в Python?Я подумал, что если я высмеиваю метод, это не должно иметь значения, если я перейду в пустой словарь или нет;что он должен просто вернуть True в этот момент.

Файл 1

def method_1(data):
    return data['header_1'] > 1

def method_2(data):
    return data['header_2'] > 1

def method_3(data):
    return data['header_3'] > 1

Файл 2

from module import file1 as f1

method_dict = {
    'method_1' : f1.method1,
    'method_2' : f1.method2,
    'method_3' : f1.method3
}

tasks_1 = ['method_1']
tasks_2 = ['method_2', 'method_3']

def function_A(data, tasks):
    results = [method_dict[task](data) for task in tasks]
    index = [i for i, result in enumerate(results) if result is True]
    return [tasks[i] for i in index] 

Тестовый файл

from module import file2 as f2
from unittest import TestCase
from unittest.mock import patch

class TestFile2(TestCase):
    @patch('module.file1.method_1')
    def test_file_2(self, mock_method_1):
        mock_method_1.return_value = True
        results = f2.function_A({}, 'tasks_1')
        expected = ['method_1']
        self.assertEqual(results, expected)
. . .

Ошибка

test/test_determine_failure_modes.py:100: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
module/file2.py:82: in function_A
    results = [task[task](data) for task in tasks]
module/file2.py:82: in <listcomp>
    results = [tasks[task](data) for task in tasks]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

data = {}

    def method_1(data):
>       return data['header_1'] > 1
E       KeyError: 'header_1'

module/file1.py:2: KeyError

1 Ответ

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

Ваш патч должен читать @patch('module.file2.f1.method_1')

Я расскажу вам, почему:

test_determine_failure_modes.py import file1 as f1.Затем file1 читается, и он определяет method1 в своих локальных компьютерах.Это становится доступным для символа f1.

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

file1: {'method1': <function>, <METHOD_1>, ...}
f1: {'method1': <function>, <METHOD_1>, ...}

Затем вы исправляете file1.method1 и получаете эту таблицу символов

file1: {'method1': <function>, MOCK, ...}
f1: {'method1': <function>, <METHOD_1>, ...}

Затем вы вызываете f1.method1 и получаете фактическую функцию.

Похоже, вы используете method_dict для ссылки на функцию, поэтому вам все же нужно немного углубиться.К счастью, unittest.mock.patch имеет утилиту для насмешки содержимого dict следующим образом:

with patch.dict(f2.method_dict, {'method1': your_mock_here}):
    your_test_here()

Еще один способ - отложить разрешение имени метода до момента его макета.

method_dict = {
    'method_1' : lambda data: f1.method1(data),
    'method_2' : lambda data: f1.method2(data),
    'method_3' : lambda data: f1.method3(data)
}

Здесь поиск f1.method1 не происходит до тех пор, пока он не подвергся насмешке.В предыдущем случае вы помещаете ссылку на функцию, когда file2 был прочитан.Здесь ссылка не разрешается до тех пор, пока метод не будет вызван.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...