我正在测试一个类,它依赖于另一个类(它的一个示例被传递给CUT的init方法),我想用Python Mock库模拟这个类。
我得到的是这样的:
mockobj = Mock(spec=MyDependencyClass)
mockobj.methodfromdepclass.return_value = "the value I want the mock to return"
assertTrue(mockobj.methodfromdepclass(42), "the value I want the mock to return")
cutobj = ClassUnderTest(mockobj)
这很好,但是“methodfromdepclass”是一个参数化的方法,因此我想创建一个单独的模拟对象,根据传递给methodfromdepclass的参数,它返回不同的值。
我想要这种参数化行为的原因是我想创建多个包含不同值的ClassUnderTest示例(这些值由mockobj返回的值产生)。
我在想什么(这当然行不通):
mockobj = Mock(spec=MyDependencyClass)
mockobj.methodfromdepclass.ifcalledwith(42).return_value = "you called me with arg 42"
mockobj.methodfromdepclass.ifcalledwith(99).return_value = "you called me with arg 99"
assertTrue(mockobj.methodfromdepclass(42), "you called me with arg 42")
assertTrue(mockobj.methodfromdepclass(99), "you called me with arg 99")
cutinst1 = ClassUnderTest(mockobj, 42)
cutinst2 = ClassUnderTest(mockobj, 99)
# now cutinst1 & cutinst2 contain different values
如何实现这种“ifcalledwith”语义?
5条答案
按热度按时间cbjzeqam1#
尝试
side_effect
vshtjzan2#
稍微甜一点:
或对于多个参数:
或使用默认值:
或两者的组合:
我们快乐地向高处走去。
bxpogfeg3#
我在做自己的测试时遇到过这种情况,如果你不关心捕捉对methodfromdepclass()的调用,而只是需要它返回一些东西,那么下面的代码就足够了:
下面是一个参数化的版本:
wswtfjt74#
与here一样,除了在unittest.mock.mock中使用
side_effect
之外,还可以将@mock.patch.object
与new_callable
一起使用,这样就可以用mock对象修补对象的属性。假设一个模块
my_module.py
使用pandas
从数据库读取数据,我们想通过模拟pd.read_sql_table
方法(以table_name
作为参数)来测试这个模块。您可以做的是(在测试中)创建一个
db_mock
方法,该方法根据提供的参数返回不同的对象:然后,在测试函数中执行以下操作:
stszievb5#
您可以使用副作用+ Dict调度模式获得更干净的代码:
例如(使用异步,忽略非异步情况下的未来对象)