使用unittest和嘲笑在python函数中修补变量

时间:2019-01-16 23:33:10

标签: python unit-testing mocking python-unittest

我具有带有create_config函数的以下my_func.py。

* my_func.py

from fabric.state import env

def create_config(node_name):
    config = {
    "log_level": "INFO",
    "addr1": "127.0.0.1",
    }
    config["addr2"] = env.host
    return config

我尝试了以下方法来模拟env.host变量,其中env是从fabric.state导入的。

* test.py

import unittest
import my_func
import mock


class MyTestCase(unittest.TestCase):
    def setUp(self):
        self.master_config = {
              "log_level": "INFO",
              "addr2": "0.0.0.0",
              "addr1": "127.0.0.1",
        }

    @mock.patch('env.host')
    def test_create_consul_config(self, mock_host):
        mock_host.return_value = "0.0.0.0"
        result = my_func.create_config('master')
        self.assertDictEqual(self.master_config, result)


if __name__ == '__main__':
    unittest.main()

我收到“ env”的导入错误。用python模拟在函数中模拟变量的最佳方法是什么。

ImportError: No module named env

2 个答案:

答案 0 :(得分:1)

  

模拟变量env.host

首先获取env的类型

In [6]: from fabric.state import env

In [7]: type(env)
Out[7]: fabric.utils._AttributeDict

env.host是一类的实例变量,其模拟有点不同,mock_env是object(AttributeDict),instance_variable主机的分配是直接分配,而不是return_value

@mock.patch('my_func.env')
def test_create_consul_config(self, mock_env):
    mock_env.host = 'xxx'
    result = my_func.create_config('master')

    self.assertDictEqual(self.master_config, result)

答案 1 :(得分:0)

unittest.mock documentation on patch(注意targetpatch的第一个参数):

  

target应该是“ package.module.ClassName”形式的字符串。的   目标被导入,指定的对象被新的替换   对象,因此目标必须可从您所在的环境中导入   从调用patch()。装饰时导入目标   函数执行,而不是在装饰时执行。

因此,您需要包括要修补的功能的完整路径。还请注意,在where to patch中,目标应该是使用功能/对象的路径,而不是定义位置。

因此将您的patch呼叫更改为:

@mock.patch("my_func.env.host")

应修复ImportError