我是python中单元测试和模拟的新手,在下面的场景我知道如何模拟没有任何参数mock example的get_name()
,但我无法模仿下面以age
为参数的场景。你能帮我修一下下面的模拟test_name
功能吗?
# data_source.py
def get_name(a):
return "Alice"+str(a)
def get_age():
return 30
Person类公开了一个从数据源中提取数据的方法:
# person.py
from data_source import get_name
class Person(object):
def name(self):
age = get_age()
return get_name(age)
from mock import patch
from person import Person
@patch('person.get_name')
def test_name(mock_get_name):
mock_get_name.return_value = "Bob"
person = Person()
name = person.name()
assert name == "Bob"
提前致谢!
答案 0 :(得分:0)
首先,除了导入get_name
之外,您还需要导入get_age
,因为您在Person类中使用它。其次,没有像person.get_name
那样定义的东西。所以你无法修补它。相反,您可能想要修补data_souce.get_name
。
但不幸的是,这不起作用,因为data_source
是一个python模块,而get_name
是其中要重新定义的方法。例如,如果get_name
是DataSource
类中的方法,则补丁装饰器会很好。我不知道它为什么不起作用的确切原因,因为我没有深入研究模拟库的实现细节,但是库的意图与你想要使用它的方式不同。
要解决此问题,您可以将data_source转换为类,或者您可以通过为其分配不同的函数或lambda来临时更改名称get_name
的含义:
import data_source
def test_person():
# replace the function
data_source._real_get_name = data_source.get_name
data_source.get_name=lamba a: "Bob"
# do some work
person = Person()
name = person.name()
# after use of the get_name function, put the original function back
data_source.get_name=data_source._real_get_name
# assert post condition
assert name=="Bob"
当然,更改哪些功能会严重影响您的程序,并且应该小心,可能仅用于测试。即使出现意外错误,也要确保始终将原始功能恢复原状。