如何测试Python函数装饰器?

时间:2011-11-02 16:19:45

标签: python unit-testing decorator

我正在尝试编写单元测试以确保我编写的各种装饰器的正确性。这是我正在尝试编写的代码的开头:

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)不会记忆中间值,因此不起作用。)测试其他装饰器的正确方法是什么?

2 个答案:

答案 0 :(得分:10)

查看标准库中的测试示例:http://hg.python.org/cpython/file/3.2/Lib/test/test_functools.py#l553

我通常会为被包装的函数添加一些工具,以便我可以监控调用。

我没有在模块级别记忆测试函数,而是在测试中创建了内部的memoized函数,以便为每个测试和每个装饰器变体创建一个新的函数。

答案 1 :(得分:2)

相当复杂的

怎么样?
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)