#python #dynamic #python-unittest #python-decorators
#питон #динамический #python-unittest #питон-декораторы
Вопрос:
Функция определяется в source.py и позвонил в use_source.py. Я исправляю это с test.py вот так
source.py
def example_function(): print("I don't want this to run")
use_source.py
from source import example_function def call_example_function(): example_function()
test.py
import unittest from unittest.mock import patch import use_source file_names = ["use_source.example_function"] def fake_function(): print("I want this to run instead") @patch(file_names[0], new=fake_function) class ExampleTest(unittest.TestCase): def test_example(self): use_source.call_example_function() if __name__ == '__main__': unittest.main()
Однако у меня есть несколько файлов, таких как use_source.py это я хочу исправить, поэтому вот мой вопрос
Как динамически вызвать декоратора исправлений с учетом списка целей?
Я ищу что-то вроде этого
@patch_list(file_names, new=fake_function) class ExampleTest(unittest.TestCase):
Я мог бы это сделать, но у меня есть большое и различное количество файлов для исправления
@patch(file_names[0], new=fake_function) @patch(file_names[1], new=fake_function) class ExampleTest(unittest.TestCase):
Наконец, я ищу решение, которое только изменяет test.py
Ответ №1:
Синтаксис декоратора-это просто синтаксический сахар для приложения функций. Ты мог бы написать
class ExampleTest(unittest.TestCase): ... for f in file_names: ExampleTest = patch(f, new=fake_function)(ExampleTest)
Я не уверен, есть ли какая-либо существенная разница между этим подходом и решением, которое вы нашли.
Комментарии:
1. спасибо, но с приведенным выше кодом я бы либо получил ссылку на «локальную переменную ‘ExampleTest’ перед назначением», либо не применял исправление, т. Е. «Я не хочу, чтобы это запускалось».
2. Я не вижу никакой причины для ошибки локальной переменной. Вы поместили цикл в инструкцию класса или после нее? (Это должно быть после, как показано на рисунке.)
3. да, ошибка локальной переменной была в операторе класса, но если я помещу цикл после оператора класса, исправление не будет применено
Ответ №2:
Я могу использовать декоратор, но использовать patch.start() в методе setUpClass теста
import unittest from unittest.mock import patch import use_source file_names = ["use_source.example_function"] def fake_function(): print("I want this to run instead") class ExampleTest(unittest.TestCase): @classmethod def setUpClass(cls): for file_name in file_names(): patch(file_name, new=fake_function).start() def test_example(self): use_source.call_example_function() if __name__ == '__main__': unittest.main()
Запуск python test.py дает тот же результат, что и выше, и позволяет мне исправлять большое и разнообразное количество методов!