如何在Python中嘲笑使用导入的PyPI库调用的函数调用

2024-04-25 09:50:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试测试以下代码:

太好了_报表.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

我有我的测试函数,它模仿来自第三方的测试函数,它测试所有的东西,但我不希望这个函数在我运行测试时暂停执行。。在

^{pr2}$

我尝试模拟重试参数,但遇到了get_link不断重试的问题,这会导致构建时间过长,而不是仅仅引发异常并继续。如何在测试中模拟@retry调用的参数?在


Tags: 代码frompyimportreport参数get报表
2条回答

正如here所暗示的,防止实际睡眠的一个简单方法是修补time.sleep函数。这是为我做到这一点的代码:

@patch('time.sleep', side_effect = lambda _: None)

无法在加载模块后更改装饰器参数。decorator装饰原始函数,并在模块加载时对其进行更改。在

首先,我想鼓励你改变一下你的设计,使它更易于测试。在

如果提取get_link()方法的主体,请测试新方法并信任retry装饰器,您将获得目标。在

如果不想在类中添加新方法,可以使用一个配置模块来存储调用retrydecorator时使用的变量。之后,您可以使用两个不同的模块进行测试和生产。在

最后一种方法是黑客攻击,您可以用您的版本替换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)

因此,你应该使用黑客的解决方案,只有当你是背在墙上,你没有机会重新设计你的代码,使其更易于测试。内部函数/类/方法可能会不经通知而更改,并且您的测试在将来很难维护。在

相关问题 更多 >