python - 如何使用生成器参数验证 Python 模拟调用
问题描述
我有一个以 aIterable
作为参数的函数:
def print_me(vals: Iterable[str]) -> None:
...
它被一个生成器调用:
def run():
print_me((str(i) for i in range(10)))
我想修补和模拟print_me()
并验证它是否被特定参数调用。使用普通的旧列表,这很容易:
mock.assert_called_with(["0", "1", ...])
但是对于生成器,因为它不能相等或重放,所以这更棘手。
解决方案
我找到了一些解决方案。我可以手动捕获参数,但如果多次调用该方法,它会变得更加混乱:
@patch('module.print_me')
def test(self, mock):
captured = None
mock.side_effect = lambda vals: captured = vals
run()
mock.assert_called_once_with(mock.ANY)
self.assertEqual(list(captured), ["0", "1", ...])
我也可以代理模拟。这使得断言干净,但想想有点奇怪,并且proxy()
每次真正函数的参数发生变化时都需要更新函数。
@patch('module.print_me')
def test(self, proxy_mock):
mock = mock.Mock()
def proxy(vals):
mock(list(vals))
proxy_mock.side_effect = proxy
run()
mock.assert_called_once_with(["0", "1"])
mock.assert_called_once_with(["2", "3"])
还有 PyHamcrest。Hamcrest 在 Java 测试中确实很受欢迎,但在 Python 中似乎没有那么受欢迎。也就是说,它做了我想要的:
@patch('module.print_me')
def test(self, mock):
run()
mock.assert_called_once_with(match_equality(contains_exactly(["2", "3"])))
推荐阅读
- anylogic - 返工产品所花费的时间 - Anylogic
- r - 如何检测以'abc'开头然后有'n'个数字然后再有字母的字符串?
- reactjs - 如何在 Javascript 中插入 HTML?
- css - Bobril - 关键帧规则
- c# - C# SmtpClient 谷歌邮件垃圾邮件文件夹
- java - 我有一个算法,但我没有修复。我该如何修复?我应该在java中做什么
- linux - 根据相应源中的内容在编辑器中打开头文件
- python - 如何根据神经网络预测改变pygame中的事件
- web-services - springboot rest api:内存和cpu始终处于高水平
- android - 无法在底部添加按钮