使用Mockito for Python模拟可调用对象时的测试异常问题
解决Mockito+py.test测试可调用对象返回值的问题
看起来你遇到的问题是因为没有正确mock匿名函数(可调用对象)的调用行为,导致测试结果不符合预期。让我们一步步分析并修复它:
问题根源分析
你的测试代码中,这一行是关键错误:
when(f).thenReturn(expected)
这里的when(f)是在尝试配置f这个mock对象的属性或方法,但并没有指定当f被调用(即执行f())时应该返回什么。Mockito默认会让未配置的mock调用返回None,所以my_function最终返回的就是None。
而换成when2时抛出TypeError,是因为when2的用法是针对函数/可调用对象的调用场景,之前的写法没有正确匹配它的参数要求。
正确的测试代码写法
我们需要明确配置:当f这个可调用对象被无参调用时,返回expected。有两种正确的实现方式:
方式1:使用when和__call__方法
直接指定mock对象的__call__方法(也就是调用行为)的返回值:
def test_my_function(when): arg = mock() f = mock() expected = mock() # 配置get_anonymous_function返回mock的f when(my_module).get_anonymous_function(arg).thenReturn(f) # 配置当f被调用时返回expected when(f).__call__().thenReturn(expected) actual = my_module.my_function(arg) assert expected == actual
方式2:使用when2(更简洁的可调用对象mock方式)
when2专门用于mock函数或可调用对象的调用,语法更直观:
from mockito import when2 def test_my_function(): arg = mock() f = mock() expected = mock() when(my_module).get_anonymous_function(arg).thenReturn(f) # 配置f无参调用时返回expected when2(f).thenReturn(expected) actual = my_module.my_function(arg) assert expected == actual
(注意:如果你的pytest fixture已经包含when2,也可以通过fixture注入,不用手动import)
额外注意点
- 确保你使用的是Mockito-Python的正确版本,不同版本的语法可能略有差异,但核心逻辑都是要明确mock可调用对象的
__call__行为。 - 如果
get_anonymous_function可能接受任意参数,你可以用any()来匹配,比如when(my_module).get_anonymous_function(any()).thenReturn(f),这样测试更灵活。
内容的提问来源于stack exchange,提问作者David Bruce Borenstein
相关产品推荐
相关产品推荐

