[英]Python: how can I import the namespace of some object to current namespace?
[英]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.py
和utils.py
的单独文件settings.py
, utils.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.