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

lus*_*sis 5 python unit-testing mocking

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

我需要做的是覆盖对 ConfigObj 的调用并将我自己的模拟配置/装置注入任何 ConfigObj 调用中。

设置.py

from configobj import ConfigObj
config = ConfigObj('/etc/myapp/config')
Run Code Online (Sandbox Code Playgroud)

实用程序.py

from settings import config
"""lots of stuff methods using various config values."""
Run Code Online (Sandbox Code Playgroud)

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

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

可以做到吗?还是 python 命名空间限制太严格,以至于我无法干预我正在导入的模块导入本身?

旁注:运行 2.7,所以我无法执行我在 2.5 中读到的任何技巧。

aar*_*ing 3

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

import configobj

class MockConfigObj(object):
     #mock whatever you wan

configobj.ConfigObj = MockConfigObj
Run Code Online (Sandbox Code Playgroud)

然后import mock在导入(从)任何本身导入的模块之前settings。这将确保settings.config使用MockConfigObj. 如果您想要统一的全局模拟,请在导入configobj.

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

虽然这让我觉得有点老套,但这是我能想到的最好的。