【发布时间】:2021-08-26 22:10:42
【问题描述】:
以下代码 sn-ps 均以python 3.7.11 运行。
我在 unittest.mock Mock 类中遇到了一些意外行为。我编写了一个单元测试,其中使用特定参数调用了 Mock,以涵盖在实际运行时预计会调用被模拟的真实对象的情况。测试通过了,所以我将构建推送到一个真实运行的设备上,以发现一个错误,即并非所有参数都传递给真实对象方法。我很快发现了我的错误,但对我来说,最初看起来我的单元测试应该失败了,而它却成功了。以下是该情况的一些简化示例。我很好奇的是,这种行为是否应该被视为我的错误或理解错误。
from `unittest.mock` import Mock
mock = Mock()
l = [1]
mock(l)
l.append(2)
mock.call_args
# Output: call([1,2])
# rather than call([1])
id(l) == id(mock.call_args[0][0])
# Output: True
# This means the l object and latest call_args reference occupy the same space in memory
这种按引用复制的行为令人困惑,因为当在同一个过程中调用函数时,预计不会在调用后将参数附加到对象中来调用该函数。
def print_var(x):
print(x)
l = [1]
print_var(l)
# Output: 1
l.append(2)
# print_var never be called with [1,2]
call_args 使用 deepcopy 来模拟我所期望的行为是否有意义?
【问题讨论】:
-
不,一直这样做是低效的(而且可能并不总是有效):bugs.python.org/issue32632。
mock.assert_called_once_with([1])没有这个问题。 -
mock.assert_called_once_with([1]) 在上面的例子中会失败,输出
AssertionError: Expected call: mock([1]) Actual call: mock([1, 2]) -
您提供的链接确实帮助我找到了解决方案,谢谢docs.python.org/3/library/unittest.mock-examples.html
标签: python-3.x unit-testing mocking