Макет класса перед импортом - PullRequest
0 голосов
/ 16 марта 2020

Я пытаюсь смоделировать метод в родительском классе, который объявлен из любого метода класса. Проблема в том, что я не могу понять, как создать экземпляр класса LoggerUtils в родительском классе. Помещать его в __ init __ не вариант из-за большого размера реализации и стоимости рефакторинга.

  • Есть ли способ смоделировать родительский класс перед импортом проверенного класса?

  • По крайней мере, смоделировать метод перед загрузкой при импорте класса.

  • Есть ли какой-нибудь подход для решения проблемы загрузки не ленивых методов при импорте?

Я пробовал ленивую загрузку TensorFlow LazyLoad Library методов, но я просто не заставил его работать; исправление всех методов с помощью фиктивной библиотеки, но методы всегда загружаются, прежде чем я смогу что-либо сделать. Ниже приведен пример попыток насмешки, но всегда вызывается LoggerUtils.

Родительский класс:

abstract_api.py

class AbstractApi:

    logger = LoggerUtils.get_logger('AbstractApi')
    def update(self):
        <code>


Класс для проверки:

api_map_asset_type.py

from abstract_api import AbstractApi


class ApiMapAssetType(AbstractApi):
    def update(self):
        <code>

Тестовый класс:

test_api_map_asset_type.py

from unittest import TestCase
from mock imort patch
from api_map_asset_type import ApiMapAssetType


class TestApiMapAssetType(TestCase):

    @patch('api_map_asset_type.AbstractApi.LoggerUtils')
    @patch('api_map_asset_type.AbstractApi')
    def setUp(self, mock2_abstract_loger, mock_3):
        self.asset_api = ApiMapAssetType()

    @patch('AbstractApi.update')
    def test_update(self, mock_parent_update):

        mock_orm = MagicMock()
        self.asset_api.update()
        mock_parent_update.assert_called_with()

EDITED

Это единственное решение, которое я нашел, так как я не могу смоделировать родительские классы или методы имитации в атрибутах классов перед импортом, я решил смоделировать весь тест перед импортом, но я думаю, что это не оптимальное или чистое решение :

Тестовый класс:

test_api_map_asset_type.py

from undetermined_project_library.LoggerUtils import LoggerUtils
with patch.object(LoggerUtils, 'get_logger') as mock_logger:

    from unittest import TestCase
    from mock imort patch
    from api_map_asset_type import ApiMapAssetType


    class TestApiMapAssetType(TestCase):

    def setUp(self):
            self.asset_api = ApiMapAssetType()

        @patch('AbstractApi.update')
        def test_update(self, mock_parent_update):

            mock_orm = MagicMock()
            self.asset_api.update()
            mock_parent_update.assert_called_with()

1 Ответ

0 голосов
/ 17 марта 2020

Если я понял схему вашего модуля, это должно сработать:

class TestApiMapAssetType(TestCase):

    @patch('undetermined_project_library.LoggerUtils')
    def setUp(self, mock_abstract_logger):
        self.asset_api = ApiMapAssetType()

    @patch('api_map_asset_type.ApiMapAssetType.update')
    def test_update(self, mock_parent_update):
        self.asset_api.update()
        mock_parent_update.assert_called_with()

Обратите внимание на пару вещей:

  • вы должны высмеивать LoggerUtils из библиотеки, в которой они находятся определено в; вы использовали AbstractApi.LoggerUtils, что неверно, поскольку LoggerUtils не относится к AbstractApi
  • Я удалил макет для AbstractApi - по крайней мере, для этого он вам не нужен
  • update исправлен для метода, который фактически вызывается - использование метода базового класса может иметь смысл, если вы вызываете базовую реализацию (не знаю, делаете ли вы это)
  • Я догадался о некоторых из макет вашего модуля - возможно, вам придется адаптировать его
...