2011-11-02 106 views
7

我想寫單元測試,以確保我寫的各種裝飾器的正確性。下面的代碼中,我試圖寫的開頭:如何測試Python函數裝飾器?

import unittest 

from memoizer import Memoizer 
from strategies.mru import MRU 


@Memoizer(strategy=MRU(maxsize=10)) 
def fib(x): 
    if x < 2: 
    return 1 
    else: 
    return fib(x-1) + fib(x-2) 


class TestMemoizer(unittest.TestCase): 

    def test_simple(self): 
    self.assertEqual(fib(0), 1) 
    self.assertEqual(fib(1), 1) 
    self.assertEqual(fib(10), 89) 


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

雖然這工作體面的MRU策略,我有以上,我打算寫額外的策略,在這種情況下,我需要與裝飾fib功能以不同的方式。 (回想一下,因爲fib叫fib,所以設置fib2 = memoize(fib)不會記憶中間值,所以不起作用。)測試其他裝飾器的正確方法是什麼?

回答

8

看看測試標準庫的例子:http://hg.python.org/cpython/file/3.2/Lib/test/test_functools.py#l553

我通常會添加一些檢測被包裝的功能,以便我可以監控呼叫。

我不是在模塊級別記憶測試功能,而是在測試中創建記憶函數,以便爲每個測試和每個裝飾變體創建一個新函數。

+0

啊,對。不知道爲什麼它沒有跨過我的腦海,不使用任何斐波那契數字。 –

+0

當您完成後,我會很樂意看到您的MRU代碼。希望你會發佈一個鏈接。 –

+0

當然!我的memoizer的代碼是在這裏:https://github.com/Ceasar/memoizer 編輯:我認爲我的mru.py實際上應該被稱爲lru.py –

1

怎麼樣的相當複雜

def mkfib(strategy): 
    @Memoizer(strategy=strategy) 
    def fib(x): 
     if x < 2: 
     return 1 
     else: 
     return fib(x-1) + fib(x-2) 
    return fib 

這種方式,你可以做

fib1 = mkfib(MRU(maxsize=10)) 
self.assertEqual(fib1(0), 1) 
self.assertEqual(fib1(1), 1) 

fib2 = mkfib(MRU(maxsize=10)) # produces another cache 
self.assertEqual(fib2(0), 1) 
self.assertEqual(fib2(1), 1) 
+0

非常聰明的主意! –