2015-08-31 44 views
2

我有一個模塊,其中包含字典作爲關聯數組來實現一種switch語句。如何在python中模擬/修補關聯數組

def my_method1(): 
    return "method 1" 


def my_method2(): 
    return "method 2" 


map_func = { 
    '0': my_method1, 
    '1': my_method2 
} 

def disptach(arg): 
    return map_func[arg]() 

如何在測試中模擬my_method1?我已經嘗試沒有成功如下:

import my_module as app 

@patch('my_module.my_method1') 
def test_mocking_sample(self, my_mock): 
    my_mock.return_value = 'mocked' 
    assert_equal('mocked',app.dispatch('0')) 

任何想法?

+1

我想你必須模擬調度('0')而不是my_method1。這是用arg'0'調用時的模擬調度。 – jgomo3

回答

1

這片patch文檔說以下內容:由(臨時)

補丁作品改變對象的名稱指向 用另一個。可以有許多名稱指向任何單個對象,因此要使修補工作起作用,您必須確保您修補了被測系統使用的名稱 。

基本上,在應用修補程序之前,調度程序基本上不會看到它,因爲映射是爲了引用原始方法而構建的。

,你可以做,使之mockable最簡單的事情是映射摺疊成dispatch功能:

def dispatch(arg): 
    return { 
    '0': my_method1, 
    '1': my_method2 
    }[arg]() 

這確實有它重建的缺點是映射每次調用它,所以它會要慢一些。

試圖變得有點聰明,它似乎是Python的讓你換出的實際代碼的函數,像這樣:

>>> f = lambda: "foo" 
>>> a = f 
>>> g = lambda: "bar" 
>>> f.func_code = g.func_code 
>>> a() 
'bar' 

我不會建議你做這種方式,但也許你可以找到一個支持類似的模擬框架。

0

正如您發現的那樣,修補程序my_Method1()不起作用。這是因爲map_func['0']是在導入my_module時定義的,並且對my_Method1()的後續更改未針對您的測試更新map_func。相反,我們需要直接在map_func字典中爲關鍵字'0'修補值。 unittest.mock documentation解釋瞭如何修補字典條目。下面是測試的工作實現:

""" test_my_module.py 
""" 
import unittest 
import unittest.mock as mock 
import my_module as app 


my_mock = mock.MagicMock() 


class Test_mock_sample(unittest.TestCase): 

    @mock.patch.dict('my_module.map_func', {'0': my_mock}) 
    def test_mocking_sample(self): 
     my_mock.return_value = 'mocked' 
     self.assertEqual('mocked', app.dispatch('0')) 

if __name__ == '__main__': 
    unittest.main() 

在原始my_module改變disptachdispatch後...

""" my_module.py 
""" 
def my_method1(): 
    return "method 1" 


def my_method2(): 
    return "method 2" 


map_func = { 
    '0': my_method1, 
    '1': my_method2 
} 

def dispatch(arg): 
    return map_func[arg]() 

然後命令python -m unittest test_my_module給出了下面的輸出:

. 
---------------------------------------------------------------------- 
Ran 1 test in 0.000s 

OK 

它的工作!