python - 为模拟 assert_call_once_with() 指定“类 Foo 的任何实例”?
问题描述
在assert_called_once_with
中,如何指定参数是“Foo 类的任何实例”?
例如:
class Foo(): pass
def f(x): pass
def g(): f(Foo())
import __main__
from unittest import mock
mock.ANY
当然通过:
with mock.patch.object(__main__, 'f') as mock_f:
g()
mock_f.assert_called_once_with(mock.ANY)
当然,另一个 Foo 实例没有通过。
with mock.patch.object(__main__, 'f') as mock_f:
g()
mock_f.assert_called_once_with(Foo())
AssertionError: Expected call: f(<__main__.Foo object at 0x7fd38411d0b8>)
Actual call: f(<__main__.Foo object at 0x7fd384111f98>)
我可以把什么作为我的预期参数,这样 Foo 的任何实例都会使断言通过?
解决方案
一个简单的解决方案是分两步执行此操作:
with mock.patch.object(__main__, 'f') as mock_f:
g()
mock_f.assert_called_once()
self.assertIsInstance(mock_f.mock_calls[0].args[0], Foo)
但是,如果您查看以下实现ANY
:
class _ANY(object):
"A helper object that compares equal to everything."
def __eq__(self, other):
return True
def __ne__(self, other):
return False
def __repr__(self):
return '<ANY>'
ANY = _ANY()
你可以看到它只是一个等于任何东西的对象。所以你可以定义你自己的等价物,它等于任何实例Foo
:
class AnyFoo:
"A helper object that compares equal to every instance of Foo."
def __eq__(self, other):
return isinstance(other, Foo)
def __ne__(self, other):
return not isinstance(other, Foo)
def __repr__(self):
return '<ANY Foo>'
ANY_FOO = AnyFoo()
或更笼统地说:
class AnyInstanceOf:
"A helper object that compares equal to every instance of the specified class."
def __init__(self, cls):
self.cls = cls
def __eq__(self, other):
return isinstance(other, self.cls)
def __ne__(self, other):
return not isinstance(other, self.cls)
def __repr__(self):
return f"<ANY {self.cls.__name__}>"
ANY_FOO = AnyInstanceOf(Foo)
无论哪种方式,您都可以像使用它一样使用它ANY
:
with mock.patch.object(__main__, 'f') as mock_f:
g()
mock_f.assert_called_once_with(ANY_FOO)
推荐阅读
- python - 创建副本时如何避免改变原始全局变量
- c# - 如何加入导航属性
- android - 无法在 AR 增强面中设置 3d 模型的正确方向
- python - 读取镶木地板文件时如何将十进制格式从点更改为逗号?
- postgresql - Postgres SSI 行为
- c - 在 C 程序中嵌入二进制文件
- javascript - 如何使用 Brain.js 查找模式
- javascript - 仅在第二次触发源 observable 后才会重新订阅
- ada - Ada - Discrete_Random 示例
- scala - 在测试设置中,Slick 无法在 reference.conf 中找到配置值(即,reference.conf 被忽略)