#python #python-mock #python-typing
Вопрос:
У меня есть некоторый метод приложения, который использует @typeguard.typechecked
декоратор для выполнения проверок во время выполнения переданных параметров:
class SalesDeal:
pass
@typechecked
def do_something(deal: SalesDeal):
pass
Внутри теста у меня есть поддельный класс FakeSalesDeal
, который реализует минимальный макет для SalesDeal
(что на самом деле очень сложный класс):
class FakeSalesDeal:
pass
def test_foo():
deal = FakeSalesDeal()
do_something(deal)
Этот тест, конечно, не пройдет, потому @typechecked
что декоратор выдаст ошибку из-за другого класса.
Есть ли способ издеваться/подделывать класс FakeSalesDeal
, чтобы пройти тест?
Комментарии:
1. Вы думали о том
FakeSalesDeal
, чтобы наследовать отSalesDeal
и просто инициализировать его с помощью множества фиктивных значений (избегая сложных аспектовSalesDeal
)?2. Да, это тоже работает.
Ответ №1:
Вы можете использовать MagicMock
с spec
установленным значением SalesDeal
вместо создания поддельного класса.
isinstance(mock, SalesDeal)
будет True
для этого макетного объекта, и вы должны быть в состоянии обойти проверку типа.
from unittest.mock import MagicMock
# ...
def test_foo():
deal = MagicMock(spec=SalesDeal)
print(isinstance(deal, SalesDeal))
do_something(deal)
test_foo()
Это печатает:
True
amp; не выдает никаких ошибок проверки типа.
Это работает, потому typechecked
что явно проверяет наличие Mock
объектов, передаваемых с:
if expected_type is Any or isinstance(value, Mock):
return
Код отсюда
Так что, если вы используете правильные насмешки, typechecked
это не должно вызывать у вас никаких проблем.
Комментарии:
1. Спасибо за указатель. Также можно наследовать от MagicMock и затем передавать проверки типов..своего рода обход, но это решает проблему.
Ответ №2:
Мое окончательное решение:
class FakeSalesDeal(MagicMock):
pass