1

我是python中单元测试和模拟的新手,在下面的场景中,我知道如何模拟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"

提前致谢!

4

1 回答 1

0

首先,除了 importing 之外get_name,你还需要 import get_age,因为你在 Person 类中使用了它。其次,没有什么像person.get_name曾经定义过的那样。所以你不能修补它。相反,您可能想要修补data_souce.get_name.

但不幸的是,这是行不通的,因为data_source它是一个 python 模块,并且get_name是一个你想要重新定义的方法。get_name例如,如果补丁装饰器是类中的一个方法,那就太好了DataSource。我不知道它不起作用的确切原因,因为我没有深入研究模拟库的实现细节,但是该库的意图与您想要使用它的方式不同。

为了解决这个问题,您可以将 data_source 转换为一个类,或者您可以get_name通过为其分配不同的函数或 lambda 来临时更改 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"

当然,更改功能会严重影响您的程序,应该小心谨慎,可能只是为了测试。确保始终将原始函数放回原处,即使意外抛出错误也是如此。

于 2013-10-21T23:57:50.343 回答