我们在python中使用Mock已经有一段时间了。
现在,我们有一个场景,我们想要模拟一个函数
def foo(self, my_param):
#do something here, assign something to my_result
return my_result
通常,模拟这种情况的方法是(假设foo是对象的一部分)
self.foo = MagicMock(return_value="mocked!")
甚至,如果我调用foo()几次,我可以使用
self.foo = MagicMock(side_effect=["mocked once", "mocked twice!"])
现在,我面临这样一种情况:当输入参数有一个特定值时,我想返回一个固定值。所以如果假设"my_param“等于"something”,那么我想返回"my_cool_mock“
这似乎可以在mockito for python上找到
when(dummy).foo("something").thenReturn("my_cool_mock")
我一直在寻找如何用Mock实现同样的目标,但没有成功?
有什么想法吗?
发布于 2013-04-23 14:19:43
如Python Mock object with method called multiple times所示
一种解决方案是编写我自己的side_effect
def my_side_effect(*args, **kwargs):
if args[0] == 42:
return "Called with 42"
elif args[0] == 43:
return "Called with 43"
elif kwargs['foo'] == 7:
return "Foo is seven"
mockobj.mockmethod.side_effect = my_side_effect
这样就行了。
发布于 2019-09-02 15:38:26
如果您想使用一个带参数的函数,但您正在模拟的函数不带参数,那么您也可以使用functools
中的partial
。例如:
def mock_year(year):
return datetime.datetime(year, 11, 28, tzinfo=timezone.utc)
@patch('django.utils.timezone.now', side_effect=partial(mock_year, year=2020))
这将返回一个不接受参数的callable (如Django的timezone.now()),但我的mock_year函数接受。
发布于 2021-01-03 16:59:53
虽然side_effect
可以实现这一目标,但为每个测试用例设置side_effect
函数并不那么方便。
我写了一个轻量级的Mock (称为NextMock)来增强内置的mock来解决这个问题,下面是一个简单的例子:
from nextmock import Mock
m = Mock()
m.with_args(1, 2, 3).returns(123)
assert m(1, 2, 3) == 123
assert m(3, 2, 1) != 123
它还支持参数匹配器:
from nextmock import Arg, Mock
m = Mock()
m.with_args(1, 2, Arg.Any).returns(123)
assert m(1, 2, 1) == 123
assert m(1, 2, "123") == 123
希望这个包能让测试变得更愉快。请随时给出任何反馈。
https://stackoverflow.com/questions/16162015
复制相似问题