在python中模拟函数的局部变量

use*_*873 8 python

我是python编程中的模拟和单元测试的新手,我如何在测试时模拟ex:age 10而不是27的函数的局部变量,请您修复以下代码。

# data_source.py
def get_name():
    age = 27 #real value
    return "Alice"

# person.py
from data_source import get_name

class Person(object):
    def name(self):
        return get_name()


from mock import patch
from person import Person

 - unit test

@patch('person.age')
def test_name(mock_age):
    mock_age = 10 # mock value
    person = Person()
    name = person.name()
    assert age == 10
Run Code Online (Sandbox Code Playgroud)

fis*_*low 6

据我所知,mock无法模拟局部变量。它只能模拟非本地对象。

尝试模拟局部变量听起来很可疑。也许你应该尝试另一种方式。尝试创建age一个全局变量或类变量。然后您可以使用mock模拟全局变量或类变量。

例如:

# source file
G_AGE = 27

def get_name():
    return "Alice"

# unit test file
...
@patch('XXX.G_AGE')
def test_name(mock_age):
    mock_age = 10
    ....
Run Code Online (Sandbox Code Playgroud)

使用时请注意patchmock如果使用不当,可能无法发挥预期效果。请参阅修补位置以获取进一步说明。


Dan*_*man 2

我无法想象你为什么要这样做。测试是为了检查您的实际函数按照编写的方式工作,而不是改变它们的工作方式以便它们匹配任意测试。

无论如何,我怀疑您想传递一个具有默认值的参数:

def get_values(age=27, name="Alice")
    ...
Run Code Online (Sandbox Code Playgroud)

  • 你这么说,但这正是编写模拟的原因:改变函数的工作方式,以便更容易/更快地测试。例如,我继承了很多已发布的 API 代码,这些代码与一些非常慢的 IO 交互。我希望能够覆盖超时变量(我的测试函数中的本地变量和常量变量),以便我可以测试异常行为,而不必等待现实世界(5-7 分钟)的超时场景。 (21认同)
  • @anregen 通过修改其环境来“改变函数的工作方式”,而不是通过修改其自身的实现。您希望可以从外部修改超时值这一事实突出表明它是“应该注入”的“依赖项”。如果您应该测试有问题的代码,则应该允许您修复它。如果没有,那么您正在测试“使用”执行 IO 的事物的客户端代码,并且您“应该模拟整个事物,而不仅仅是其超时值”。即使超出代码组织范围,您也不希望测试依赖于 IO 成功! (3认同)
  • 您可能需要模拟从远程进程或 API 调用返回的变量的成功/失败。 (2认同)