我正在尝试测试以下代码:
great_report.py
from retry import retry
@retry((ReportNotReadyException), tries=3, delay=10, backoff=3)
def get_link(self):
report_link = _get_report_link_from_3rd_party(params)
if report_link:
return report_link
else:
stats.count("report_not_ready", 1)
raise ReportNotReadyException
我有我的测试函数,该函数模拟_get_report_link_from_3rd_party对所有内容进行测试,但是我不希望该函数在运行测试期间实际暂停执行。
@mock.patch('repo.great_report._get_report_link_from_3rd_party', return_value=None)
test_get_link_raises_exception(self, mock_get_report_link):
self.assertRaises(ReportNotReadyException, get_link)
我尝试模拟重试参数,但是遇到了以下问题:get_link不断重复尝试,这会导致较长的构建时间,而不仅仅是引发异常并继续。如何在测试中模拟@retry调用的参数?
加载模块后无法更改装饰器参数。装饰器装饰原始功能,并在模块加载时对其进行更改。
首先,我想鼓励您稍微更改一下设计以使其更具可测试性。
如果您提取get_link()
方法主体测试新方法和信任retry
装饰器,那么您将实现目标。
如果您不想在类中添加新方法,则可以使用配置模块,该模块存储在调用retry
装饰器时使用的变量。之后,您可以使用两个不同的模块进行测试和生产。
最后一种方法是黑客方式,您可以retry.api.__retry_internal
通过只更改变量来替换调用原始版本的版本:
import unittest
from unittest.mock import *
from pd import get_link, ReportNotReadyException
import retry
orig_retry_internal = retry.api.__retry_internal
def _force_retry_params(new_tries=-1, new_delay=0, new_max_delay=None, new_backoff=1, new_jitter=0):
def my_retry_internals(f, exceptions, tries, delay, max_delay, backoff, jitter, logger):
# call original __retry_internal by new parameters
return orig_retry_internal(f, exceptions, tries=new_tries, delay=new_delay, max_delay=new_max_delay,
backoff=new_backoff, jitter=new_jitter, logger=logger)
return my_retry_internals
class MyTestCase(unittest.TestCase):
@patch("retry.api.__retry_internal", side_effect=_force_retry_params(new_tries=1))
def test_something(self, m_retry):
self.assertRaises(ReportNotReadyException, get_link, None)
恕我直言,仅当您背靠墙且没有机会重新设计代码以使其更具可测试性时,才应使用该黑客解决方案。内部函数/类/方法可能会更改,恕不另行通知,并且将来可能很难维护您的测试。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句