2011-11-02 100 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

非常聪明的主意! –