блочное тестирование и множественное наследование: ошибка типа: конфликт метаклассов - PullRequest
0 голосов
/ 06 июня 2018

У меня есть пакет, зависимость которого не установлена ​​pip.Чтобы создать документацию, я пытаюсь смоделировать неинсталлируемый пакет, используя MagicMock.

Однако я наткнулся на проблему с множественным наследованием: когда один изродительские классы - это фиктивный класс, который я получаю:

TypeError: конфликт метакласса: метакласс производного класса должен быть (нестрогим) подклассом метаклассов

Следующий пример иллюстрирует проблему:

файл: class_a.py

class A:
    pass

файл: code.py

from class_a import A

class B:
    pass

class C(A, B):
    pass

file: test.py

import sys
from unittest import mock

# inspired by https://stackoverflow.com/a/37363830/1860757
MOCK_MODULES = ['class_a', ]
sys.modules.update((mod_name, mock.MagicMock()) for mod_name in MOCK_MODULES)

import code

code.C()

Если я запускаю python3 test.py, я получаю указанное выше исключение.Если я прокомментирую строку, начинающуюся с sys.modules.update, все будет работать так, как ожидается.

Есть ли способ смоделировать модули или классы так, чтобы множественное наследование продолжало работать?

1 Ответ

0 голосов
/ 20 июня 2018

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

import sys
from unittest import mock


class _A:
    pass

MOCK_MODULES = ['class_a', ]
sys.modules.update((mod_name, mock.MagicMock()) for mod_name in MOCK_MODULES)
patcher = mock.patch('class_a.A', new=_A)
patcher.start()


import code


code.C()

patcher.stop()

Если кто-то в будущем найдет новый / лучший способ, пингуйте меня, и я переоценю принятый ответ.

...