Python MagicMock属性是静态的

时间:2017-07-20 12:03:03

标签: python unit-testing testing mocking

考虑我必须对以下功能进行单元测试:

def f(A):
    tasks = []

    for i in range(0, 3):
        task = A.tasks.create()
        task.attr = i

        tasks.append(task)

    return tasks

当我模拟A函数的f参数时,会发生这种情况:

>>> A = mock.MagicMock()
>>> tasks = f(A)

>>> for task in tasks:
>>>    print(task.attr)

Out: 2 2 2

我期待以下输出:0 1 2,为什么我会这样做,我该如何解决?感谢。

1 个答案:

答案 0 :(得分:0)

由于AMagicMockA.tasksA.tasks.create也是MagicMock。当您调用最后一个时,它总是返回对相同 task.attr = i实例的引用,因此attr会覆盖同一MagicMock的{​​{1}}属性}。 tasks是对同一MagicMock实例的三个引用的列表。

>>> from unittest import mock
>>> A = mock.MagicMock()
>>> A.tasks.create()
<MagicMock name='mock.task.create()' id='4486337536'>
>>> A.tasks.create()
<MagicMock name='mock.task.create()' id='4486337536'>
>>> A.tasks.create()
<MagicMock name='mock.task.create()' id='4486337536'>

(注意所有三个的id都相同。)

每次调用create时获取新模拟任务的一种方法是明确地将MagicMock分配给create模拟的tasks属性:

>>> A = mock.MagicMock()
>>> A.tasks.create = mock.MagicMock
>>> A.task.create()
<MagicMock id='4485133648'>
>>> A.task.create()
<MagicMock id='4485176176'>