gpt4 book ai didi

python - 如何模拟对接收可变对象作为参数的函数的调用?

转载 作者:太空宇宙 更新时间:2023-11-04 03:35:00 25 4
gpt4 key购买 nike

考虑示例:

def func_b(a):
print a

def func_a():
a = [-1]
for i in xrange(0, 2):
a[0] = i
func_b(a)

以及尝试测试 func_a 和模拟 func_b 的测试函数:

import mock
from mock import call

def test_a():
from dataTransform.test import func_a
with mock.patch('dataTransform.test.func_b', autospec=True) as func_b_mock:
func_a()
func_b_mock.assert_has_calls([call(0), call(1)])

在 func_a 执行后,我尝试测试 func_a 是否对 func_b 进行了正确的调用,但由于在 for 循环中,我最终改变了列表,我得到:

AssertionError: Calls not found.
Expected: [call(0), call(1)]
Actual: [call([1]), call([1])]

最佳答案

以下工作(从 unittest 导入 mock 是 Python 3 的事情,modulefunc_afunc_b 是):

import mock
from mock import call
import copy

class ModifiedMagicMock(mock.MagicMock):
def _mock_call(_mock_self, *args, **kwargs):
return super(ModifiedMagicMock, _mock_self)._mock_call(*copy.deepcopy(args), **copy.deepcopy(kwargs))

继承自MagicMock,重新定义调用行为,对参数和关键字参数进行deepcopy。

def test_a():
from module import func_a
with mock.patch('module.func_b', new_callable=ModifiedMagicMock) as func_b_mock:
func_a()
func_b_mock.assert_has_calls([call([0]), call([1])])

您可以使用 new_callable 参数将新类传递到 patch 中,但是它不能与 autospec 共存。请注意,您的函数使用列表调用 func_b,因此 call(0), call(1) 必须更改为 call([0]), call ([1])。当通过调用 test_a 运行时,它什么都不做(通过)。

现在我们不能同时使用 new_callableautospec 因为 new_callable 是一个通用工厂,但在我们的例子中只是一个 MagicMock 覆盖。但是Autospeccing是一个非常酷的 mock 功能,我们不想失去它。

我们需要的是将 MagicMock 替换为 ModifiedMagicMock 只是为了我们的测试:我们希望避免更改所有测试的 MagicMock 行为......可能很危险。我们已经有一个工具可以做到这一点,它是 patch,与 new 参数一起使用以替换目标。

在这种情况下,我们使用装饰器来避免缩进过多并使其更具可读性:

@mock.patch('module.func_b', autospec=True)
@mock.patch("mock.MagicMock", new=ModifiedMagicMock)
def test_a(func_b_mock):
from module import func_a
func_a()
func_b_mock.assert_has_calls([call([0]), call([1])])

或者:

@mock.patch("mock.MagicMock", new=ModifiedMagicMock)
def test_a():
with mock.patch('module.func_b') as func_b_mock:
from module import func_a
func_a()
func_b_mock.assert_has_calls([call([0]), call([1])])

关于python - 如何模拟对接收可变对象作为参数的函数的调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29516339/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com