繁体   English   中英

如何在python中将对象注入另一个命名空间?

[英]How can I inject an object into another namespace in python?

我正在为办公室里的其他人写的代码编写一些单元测试。 Python不是我最强的语言。 虽然我已经成功进行了基本的单元测试,但是在python中进行模拟会让我陷入困境。

我需要做的是覆盖对ConfigObj的调用,并将我自己的mock config / fixture注入任何ConfigObj调用。

settings.py

from configobj import ConfigObj
config = ConfigObj('/etc/myapp/config')

utils.py

from settings import config
"""lots of stuff methods using various config values."""

我想做的是,在我的utils.py单元测试中,注入我自己的任何调用ConfigObj或settings.py本身。

许多模拟库希望我模拟我自己的类,但在这个应用程序的情况下,它没有任何显式类。

它可以完成还是python命名空间限制太严格,我不能介入我正在导入的模块导入自己?

旁注:运行2.7所以我不能做任何我从2.5中读过的技巧。

如果测试位于settings.pyutils.py的单独文件settings.pyutils.py可以创建文件mock.py

import configobj

class MockConfigObj(object):
     #mock whatever you wan

configobj.ConfigObj = MockConfigObj

然后在导入(从)任何自身导入settings模块之前import mock 这将确保settings.config与创建MockConfigObj 如果您想要统一的全局configobj ,请在导入configobj任何文件之前导入它。

这是有效的,因为python会在sys.modules存储configobj ,并在实际读取后续导入文件之前检查它。 mock.py ,标识符ConfigObj只是对sys.modules条目的引用,因此您所做的任何更改都将是全局可见的。

这让我觉得有点哈哈,但这是我能想到的最好的。

Python命名空间在同一范围内根本不严格。 只需覆盖包含您的对象(或类本身并提供它)的变量名称,在您期望原始的同一范围内,这就足够了。

现在,你取而代之的行为是否相同取决于你......

以下页面是关于模拟和导入的好页面

http://www.relaxdiego.com/2014/04/mocking-objects-in-python.html

假设您有一个名为my_package1.py的文件,其中包含以下代码:

class A(object): def init (self):

然后使用代码在my_package2.py中导入它

from my_package1 import A class A(object): def init (self):

my_package2.py的第一行在名为A的my_package2名称空间下创建一个变量。现在你有两个变量my_package1.A和my_package2.A,它们都指向内存中的同一个类。 如果你想让my_package2.py中的代码使用模拟的类A,那么你需要模拟my_package2.A而不是my_package1.A

难道你不能用另一个覆盖原来的功能吗?

Python中没有常量,你可以改变一切,你甚至可以做True = False

我之前遇到过类似的情况。 以下是我将如何解决您的问题。

考虑utils.py函数的utils.py

import utils, unittest

class FooFunctionTests(unittest.TestCase):
    def setUp(self):
        utils._old_config = utils.config
        utils.config = MockClass()

    def tearDown(self):
        utils.config = utils._old_config
        del utils._old_config

    def test_foo_function_returns_correct_value(self):        
        self.assertEqual("success!", utils.foo())

暂无
暂无

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

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