python - 如何在 python 包中测试装饰器

标签 python decorator python-unittest

我正在编写我的第一个 python 包,我想为以下装饰器编写单元测试:

class MaxTriesExceededError(Exception):
    pass

def tries(max_tries=3, error_message=os.strerror(errno.ETIME)):
    def decorator(func):
        try_count = 0
        def wrapper(*args, **kwargs):
            try_count+=1
            try:
                if try_count <= max_tries:
                    result = func(*args,**kwargs)
                    return result
                else:
                    raise MaxTriesExceededError(error_message)
            except:
                if try_count <= max_tries:
                    wrapper(*args,**kwargs)
                else:
                    raise Exception

        return wraps(func)(wrapper)

    return decorator

装饰器的目的是如果函数失败次数超过 max_tries 则抛出错误,但如果未超过最大尝试次数则吃掉错误并重试。老实说,我不确定代码没有错误。因此,我的问题是双重的,代码是否正确,以及如何使用 unittest 为其编写单元测试?

最佳答案

这是一个更正后的版本,带有单元测试:

class MaxTriesExceededError(Exception):
    pass

def tries(max_tries=3, error_message="failure"):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for try_count in range(max_tries):
              try:
                return func(*args,**kwargs)
              except:
                pass
            raise MaxTriesExceededError(error_message)
        return wrapper
    return decorator


import unittest

class TestDecorator(unittest.TestCase):

  def setUp(self):
      self.count = 0

  def test_success_single_try(self):
      @tries(1)
      def a():
          self.count += 1
          return "expected_result"
      self.assertEqual(a(), "expected_result")
      self.assertEqual(self.count, 1)

  def test_success_two_tries(self):
      @tries(2)
      def a():
          self.count += 1
          return "expected_result"
      self.assertEqual(a(), "expected_result")
      self.assertEqual(self.count, 1)

  def test_failure_two_tries(self):
      @tries(2)
      def a():
           self.count += 1
           raise Exception()
      try:
        a()
        self.fail()
      except MaxTriesExceededError:
        self.assertEqual(self.count,2)

  def test_success_after_third_try(self):
      @tries(5)
      def a():
           self.count += 1
           if self.count==3:
             return "expected_result"
           else:
             raise Exception()
      self.assertEqual(a(), "expected_result")
      self.assertEqual(self.count, 3)

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

关于python - 如何在 python 包中测试装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34648337/

相关文章:

python - 在 Python 中对嵌套对象(DynamoDB 和表)使用 Mock

python - 抓取/忽略空项目

python - 排序不适用于我的热图

python - PyMongo 装饰器变量到函数上下文

grails - 从其他数据源获取信息以在Grails上更新我自己的信息

python - 避免 Python Unittest 中的包名称冲突

python - 'getattr() : attribute name must be string' error in admin panel for a model with an ImageField

python - 无法制作自定义 Django View 装饰器(带参数)

python - 一个多余但很酷的动态 python 结构以及关于装饰器、推导式、语法的问题

python - 修补从模拟类调用的类函数