简体   繁体   English

使用单元测试和模拟修补 python 函数中的变量

[英]Patching variable in a python function with unittest and mock

I have the following my_func.py with create_config function.我有以下带有 create_config 函数的 my_func.py。

*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

I tried the following approach to mock env.host variable where env is an import from fabric.state.我尝试了以下方法来模拟 env.host 变量,其中 env 是从 fabric.state 导入的。

*test.py *测试.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()

I am getting import error with 'env'.我收到'env'的导入错误。 What is the best way to mock variable within a function with python mock.使用 python 模拟在函数中模拟变量的最佳方法是什么。

ImportError: No module named env

mock variable env.host ?模拟变量env.host

get the type of env first首先获取env的类型

In [6]: from fabric.state import env

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

env.host is instance variable of a class, the mock is a little different, mock_env is object(AttributeDict), the assignment of instance_variable host is direct assignment, not with a return_value env.host是一个类的实例变量,mock有点不同,mock_env是object(AttributeDict),instance_variable host的赋值是直接赋值,不带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)

From the unittest.mock documentation on patch (note target is the first argument of patch ):来自关于 patchunittest.mock 文档(注意targetpatch的第一个参数):

target should be a string in the form 'package.module.ClassName'. target 应该是“package.module.ClassName”形式的字符串。 The target is imported and the specified object replaced with the new object, so the target must be importable from the environment you are calling patch() from.目标被导入并且指定的对象被新对象替换,因此目标必须可以从您调用 patch() 的环境中导入。 The target is imported when the decorated function is executed, not at decoration time.目标是在执行装饰函数时导入的,而不是在装饰时导入。

So you need to include the full path to the function you are patching.因此,您需要包含要修补的函数的完整路径。 Note also in where to patch that the target should be the path to where the function/object is used, not where it is defined.还要注意在哪里打补丁,目标应该是使用函数/对象的路径,而不是定义它的位置。

So changing your patch call to:因此,将您的patch调用更改为:

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

should fix the ImportError .应该修复ImportError

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM