2012-09-25 82 views
7

假設我們有一個只存在於生產階段的模塊系統。在測試這些模塊時不存在。但是我仍然想爲使用這些模塊的代碼編寫測試。我們還假設我知道如何模擬這些模塊中的所有必要對象。問題是:我如何方便添加模塊存根到當前層次?如何模擬不存在的模塊的層次結構?

這是一個小例子。我想測試的功能被放置在一個名爲actual.py文件:

actual.py: 


def coolfunc(): 
    from level1.level2.level3_1 import thing1 
    from level1.level2.level3_2 import thing2 
    do_something(thing1) 
    do_something_else(thing2) 

在我的測試套件我已經有我需要的一切:我有thing1_mockthing2_mock。另外我有一個測試功能。我需要的是將level1.level2...添加到當前模塊系統中。就像這樣:

tests.py 

import sys 
import actual 

class SomeTestCase(TestCase): 
    thing1_mock = mock1() 
    thing2_mock = mock2() 

    def setUp(self): 
    sys.modules['level1'] = what should I do here? 

    @patch('level1.level2.level3_1.thing1', thing1_mock) 
    @patch('level1.level2.level3_1.thing1', thing2_mock) 
    def test_some_case(self): 
    actual.coolfunc() 

我知道我可以包含其他對象等對象代替sys.modules['level1']。但它對我來說似乎有很多代碼。我認爲必須有更簡單更漂亮的解決方案。我無法找到它。

回答

9

因此,沒有人幫助我解決問題,我決定自己解決。 Here是一個名爲surrogate的微庫,它允許爲不存在的模塊創建存根。

庫可以與mock這樣使用:

from surrogate import surrogate 
from mock import patch 

@surrogate('this.module.doesnt.exist') 
@patch('this.module.doesnt.exist', whatever) 
def test_something(): 
    from this.module.doesnt import exist 
    do_something() 

首先@surrogate裝飾創建不存在的模塊存根,然後@patch裝飾可以改變它們。正如@patch,@surrogate裝飾器可以「複數」使用,從而樁住多個模塊路徑。所有存根僅在裝飾函數的生命週期中存在。

如果任何人有任何使用這個庫,這將是偉大的:)