Python 可变参数函数的测试

Python 可变参数函数的测试,python,pytest,Python,Pytest,我正在为一个函数编写一些测试,该函数将的一个实例传递给另一个需要模拟的函数。下面是一个代表我的代码的小示例: #“bar”模块 def回调(计数器): “”“使用*计数器*执行某些操作”“” 通过 def update(): “”“更新计数器并将其传递给回调。”“” 计数器=集合。计数器() 对于范围(3)内的uu: 计数器更新([“foo”]) 回调(计数器) 以下测试未通过,因为相同的计数器实例已被变异并传递给“callback”函数。因此,只有当所有调用都采用计数器的最新值时,断言才会通

我正在为一个函数编写一些测试,该函数将的一个实例传递给另一个需要模拟的函数。下面是一个代表我的代码的小示例:

#“bar”模块
def回调(计数器):
“”“使用*计数器*执行某些操作”“”
通过
def update():
“”“更新计数器并将其传递给回调。”“”
计数器=集合。计数器()
对于范围(3)内的uu:
计数器更新([“foo”])
回调(计数器)
以下测试未通过,因为相同的计数器实例已被变异并传递给“callback”函数。因此,只有当所有调用都采用计数器的最新值时,断言才会通过,即
collections.counter({“foo”:3})

@pytest.fixture()
def mocked_回调(mocker):
返回mocker.patch(“bar.callback”)
def测试_更新(模拟、模拟_回调):
更新()
assert mocked_callback.call_args_list==[
mocker.call(collections.Counter({“foo”:1})),
mocker.call(collections.Counter({“foo”:2})),
mocker.call(collections.Counter({“foo”:3})),
]

是否有人知道一种好方法,可以在将变异对象传递给模拟函数时分析其确切状态?

此问题实际上在中引用

另一种情况很少见,但可能会影响您,即使用可变参数调用mock。call_args和call_args_list存储对参数的引用。如果参数被测试代码改变,那么您就不能再断言调用mock时的值是什么

建议的解决方案似乎非常有效

@pytest.fixture()
def mocked_回调(mocker):
类_CopyingMock(mocker.MagicMock):
“”“扩展Mocker以复制每次调用的参数。”“”
定义调用(self,*args,**kwargs):
args=copy.deepcopy(args)
kwargs=copy.deepcopy(kwargs)
返回超级(_MagicMock,self)。_调用(*args,**kwargs)
返回mocker.patch(“bar.callback”,_CopyingMock())
核心库中包含此功能的票证:


您确定模拟的功能正确吗?测试用例中的
\uuuuu name\uuuuuuuuuuuuuuuuuuuuuu
可能与您尝试测试的模块的名称不同……这里的代码中有几个错误(提到的
\uuuuuuu name\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
,以及
回调
做某事
的混合),但基本问题是调用引用了在调用期间更新的dict,因此在调用之后,所有调用都指向相同(最终)dict
{“foo”:3}
(而不是
{“foo”:1}
)。我不知道该怎么解决这个问题…谢谢,我修正了你发现的打字错误。另外,我真正的测试与它正在测试的代码没有混合在同一个模块中,我只是用
\uuuu name\uuuu
提供了一个可复制的示例:)@mrbeanbreman这正是我试图解决的问题是的。现在我唯一的解决办法是使用
collections.Counter.update
而不是检查回调的参数,但我觉得一定有更好的方法..很好!实际上,我认为这是一个解决办法(刚才是写一个各自的评论),但我不知道文档中有这样的内容。实际上,我正要询问pytest mock repo时,我在一个网站上打了个短截图,我在这里找到了链接:)