1

是否有可能伪造我在测试中使用的其他模块使用(导入)的模块?

示例:这是我的 test.py:

import unittest 
import module1
//test code here
module1.some_method()
//test code here

这是module1.py:

import module_i_want_to_fake
//module code here

基于示例:问题是:我如何module_i_want_to_fake在 test.py中伪造

4

2 回答 2

3

当您执行 时import foo,如果sys.modules['foo']已经存在,解释器只会返回它而不是执行新的导入。

因此,要伪造 outmodule1import声明,只需在 load 之前填写值module1。这有点hacky,但非常简单。例如:

我的测试.py:

import sys
import unittest 
import my_fake_module
sys.modules['module_i_want_to_fake'] = my_fake_module
import module1
//test code here
module1.some_method()
//test code here

模块1.py:

import module_i_want_to_fake
print(module_i_want_to_fake)

这将打印出如下内容:

<module 'my_fake_module' from 'my_fake_module.pyc'>

如果您需要module1更彻底地伪造(即使它试图自省模块),您可以创建一个新模块(通过types.ModuleType),其中的代码来自my_fake_modulename 'module_i_want_to_fake',以及您想要的任何其他更改。

如果您需要比仅通过预先静态重命名模块更动态地执行此操作,您可以构建一个导入挂钩,如PEP 302中所述。这需要您重新实现大量的导入机制,这在 2.x 中是一个巨大的痛苦,但importlib在 3.1+ 中使它变得容易得多。

幸运的是,通常情况下,您不需要执行其中任何一项。

于 2013-03-13T20:50:56.190 回答
0

在 python3 我这样做:

在模块中创建简单的假类

# module test.py
thismodule = sys.modules[__name__]
setattr(thismodule, "something", type("something", (), {}))

这很酷,但您可能想要的是从配置数据文件生成。

从 cfg 文件在模块中创建假类

# module test.py
import configparser

cfg = configparser.ConfigParser()
cfg.read("/path/to/fname.ini")

for section in cfg.sections():
    name = cfg[str(section)]['name']
    setattr(thismodule, name, type(name, (), {}))

好的,现在让我们在module1中尝试

# Import only the main module
import test

# now you can use as you want
test.something

享受!!

于 2014-11-28T16:53:57.550 回答