如何在测试运行时类型检查期间模拟 Python class?
How to mock a Python class during testing for runtime typing checks?
我有一些应用程序方法使用 @typeguard.typechecked
装饰器对传递的参数执行运行时检查:
class SalesDeal:
pass
@typechecked
def do_something(deal: SalesDeal):
pass
在一个测试中,我有一个假的 class FakeSalesDeal
,它为 SalesDeal
实现了一个最小的模拟(这在现实中是一个非常复杂的 class):
class FakeSalesDeal:
pass
def test_foo():
deal = FakeSalesDeal()
do_something(deal)
这个测试当然会失败,因为 @typechecked
装饰器会由于不同的 class.
而引发错误
有没有办法 mock/fake FakeSalesDeal
的 class 使测试通过?
您可以使用 MagicMock
并将 spec
设置为 SalesDeal
,而不是创建假的 class。
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
& 不会抛出任何类型检查错误。
这是有效的,因为 typechecked
显式检查 Mock
传递的对象:
if expected_type is Any or isinstance(value, Mock):
return
代码来自 here
因此,如果您使用适当的模拟,typechecked
应该不会给您带来任何问题。
我的最终解决方案:
class FakeSalesDeal(MagicMock):
pass
我有一些应用程序方法使用 @typeguard.typechecked
装饰器对传递的参数执行运行时检查:
class SalesDeal:
pass
@typechecked
def do_something(deal: SalesDeal):
pass
在一个测试中,我有一个假的 class FakeSalesDeal
,它为 SalesDeal
实现了一个最小的模拟(这在现实中是一个非常复杂的 class):
class FakeSalesDeal:
pass
def test_foo():
deal = FakeSalesDeal()
do_something(deal)
这个测试当然会失败,因为 @typechecked
装饰器会由于不同的 class.
有没有办法 mock/fake FakeSalesDeal
的 class 使测试通过?
您可以使用 MagicMock
并将 spec
设置为 SalesDeal
,而不是创建假的 class。
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
& 不会抛出任何类型检查错误。
这是有效的,因为 typechecked
显式检查 Mock
传递的对象:
if expected_type is Any or isinstance(value, Mock):
return
代码来自 here
因此,如果您使用适当的模拟,typechecked
应该不会给您带来任何问题。
我的最终解决方案:
class FakeSalesDeal(MagicMock):
pass