Насмешка над объектом в удаленном модуле - PullRequest
0 голосов
/ 21 апреля 2020

У меня есть несколько юнит-тестов, которые я провожу в классе, ClassA. Этот класс имеет методы, которые вызывают ClassB. ClassA и ClassB находятся в отдельных модулях, class_A.py и class_B.py. Оба этих модуля имеют функции logger, которые доступны глобально в этом модуле.

Во время моего тестирования методов ClassA я хочу подавить сообщения регистрации. Используя mock.patch, это просто сделать для регистратора в class_A.py. Но я не нашел способа исправления регистратора в class_B.py.

Вот пример кода:

unittest_file.py

import unittest
import class_A

class TestClassA(unittest.TestCase):

    def setUp(self):
        pass

    def test_method(self):
        my_class_A = class_A.ClassA()
        my_class_A.run_method()

    def tearDown(self):
        pass

class_A.py

import logging
from class_B import ClassB

logger = logging.getLogger(__name__)

class ClassA:

    run_method(self):
        my_class_B = ClassB()
        my_class_B.do_something()
        logger.info("Running method on Class A")

class_B.py

import logging

logger = logging.getLogger(__name__)

class ClassB:

    do_something(self):
        logger.info("Doing something on Class B")

Чтобы установить логгер в class_A.py Я могу добавить @patch('__main__.unittest_file.ClassA.logger', autospec=True) в качестве декоратора для метода test_method(). Но у меня нет прямого доступа к логгеру в class_B.py для его исправления.

Самое близкое решение, которое я нашел, это:

@patch(eval('__main__.unittest_file.class_A.ClassB.__module__')['logger'])

, но функция eval(), примененная к имени модуля, не сохраняет местоположение импорта, поэтому она не исправляет регистратор в нужном пространстве имен.

Я знаю, что могу легко решить эту проблему, изменив оператор import в class_A.py до import class_B вместо from class_B import ClassB, но я не хочу редактировать код в class_A.py или class_B.py, так что это не тот ответ, который я ищу.

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

Мой вопрос: есть ли способ, с помощью которого я могу перемещаться от импортированного объекта к другим объектам в его родительском модуле, оставаясь в том же самом? Пространство имен?

1 Ответ

1 голос
/ 21 апреля 2020

Для меня просто исправление class_A.logger и class_B.logger работает, например

import unittest
from unittest import mock

class TestCaseA(unittest.TestCase):

    @mock.patch('class_A.logger')
    @mock.patch('class_B.logger')
    def test_method(self, mockedA, mockedB):
        my_class_A = ClassA()
        my_class_A.run_method()

Оба регистратора больше не выводят сообщения журнала.

...