2013-03-13 185 views
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。 py

+1

是什麼原因?你可以'將module1導入爲m1'或者使用其他名稱作爲參考。 – ninMonkey 2013-03-13 20:42:41

+0

但是當我導入module1時,module1會導入module_i_want_to_fake,但我想導入my_fake_module – 2013-03-13 20:47:06

+0

因此,您希望從'module1'之外攔截其「import」語句,以便您可以替換不同的模塊? – abarnert 2013-03-13 20:47:42

回答

3

當你做一個import foo,如果sys.modules['foo']已經存在,解釋器只是返回,而不是做一個新鮮的進口。

因此,要僞造module1import聲明,只需在加載module1之前獲取填充的值。這有點哈克,但很簡單。例如:

mytest.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 

module1.py:如果您需要假了

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

import module_i_want_to_fake 
print(module_i_want_to_fake) 

這將打印出這樣的事情module1更徹底(即使它試圖反思模塊),你可以創建一個新的模塊(通過types.ModuleType),代碼爲my_fake_module,但名稱爲'module_i_want_to_fake',以及其他所需的更改。

如果您需要更動態地完成此操作,而不是僅通過事先靜態地重命名模塊即可完成此操作,則可以構建導入掛鉤,如PEP 302中所述。這需要你重新實現一大塊導入機制,這在2.x中是一個巨大的痛苦,但是在3.1+中的importlib使得它更容易。

幸運的是,通常情況下,您不需要執行其中任何一項。

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,(), {})) 

好了,現在讓我們嘗試在模塊1

# Import only the main module 
import test 

# now you can use as you want 
test.something 

享受!