Тестирование неабстрактного метода абстрактного класса в Python - PullRequest
0 голосов
/ 07 октября 2019

У меня есть проблема, похожая на упомянутую здесь . Тем не менее, я считаю, что мои классы немного отличаются.

Вот что у меня есть:

A.py:

from [...] import B

class A(ABC):
    def __init__(self):
        self.b = B()

    def get_data(self):
        for-loop:
            x = self.b.methodA(x)

    @abstractmethod
    def update(self):
        pass

B.py:

class B:
    def methodA(self, x):
        # Do something here

Я пытаюсь протестировать класс 101 * без использования его подкласса (ов).

В моем методе тестирования я исправляю methodA(), так как я не хочу проверять вызов API. Для того чтобы я смог протестировать неабстрактный метод в абстрактном классе без создания экземпляров подкласса, я использовал следующий код:

abstract_concreter.py:

def concreter(A):
    if "__abstractmethods__" not in A.__dict__:
        return A
    new_dict = A.__dict__.copy()
    for abstractmethod in A.__abstractmethods__:
        new_dict[abstractmethod] = lambda x, *args, **kwargs: (x, args, kwargs)
    return type('dummy_concrete_{}'.format(A.__name__), (A,), new_dict)

Мой метод теста выглядиткак это:

@patch('<path>.A.B.methodA', spec=True)
    def test_get_data(self, mock_fn):
        concreter(A).get_data(self, x=123)
        print(mock_fn)  # <MagicMock name='methodA' spec='function' id='74741552'>
        mock_fn.assert_called_with(123)

И все же я получаю следующую ошибку:

AssertionError: Expected call: methodA(123)
Not called

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

Ура

...