根据第三方服务测试功能



我正在尝试弄清楚如何为函数创建单元测试,哪种行为基于第三方服务。

假设这样的函数:

def sync_check():
    delta_secs = 90
    now = datetime.datetime.now().utcnow()
    res = requests.get('<url>')
    alert = SlackAlert()
    last_value = res[-1]['date'] # Last element of the array is the most recent
    secs = (now - last_value).seconds
    if secs >= delta_secs:
        alert.notify("out of sync. Delay: {} seconds".format(secs))
    else:
        alert.notify('in sync')

为此功能编写单元测试的最佳实践是什么?我需要测试IF和其他分支,但这取决于第三方服务。

我想到的第一件事是创建一个伪造的网络服务器并指向该网络服务器(更改URL),但是这种方式代码库将包括测试逻辑,例如:

if test:
    url = <mock_web_server_url>
else:
    url = <third_party_service_url>

此外,单元测试将触发松弛警报,这不必发生。

所以我应该再次更改代码库,例如:

if secs >= delta_secs:
    if test:
        logging.debug("out of sync alert sent - testing mode")
    else:
        alert.notify("out of sync. Delay: {} seconds".format(secs))
else:
    if test:
        logging.debug("in sync alert sent - testing mode")
    else:
        alert.notify('in sync')

我真的不喜欢。

我是否缺少任何解决此问题的设计?

查看依赖于第三方服务的测试代码的依赖项注入,而不必检查您是否在测试模式下运行,例如在示例中。基本想法是让Slack Alert服务是您功能的参数,因此,对于单元测试,您可以使用以您需要的方式来执行每个测试的方式。

您的代码最终会看起来像这样:

def sync_check(alert):
    delta_secs = 90
    now = datetime.datetime.now().utcnow()
    res = requests.get('<url>')
    last_value = res[-1]['date'] # Last element of the array is the most recent
    secs = (now - last_value).seconds
    if secs >= delta_secs:
        alert.notify("out of sync. Delay: {} seconds".format(secs))
    else:
        alert.notify('in sync')

,在测试案例中,您可以让您的警报对象很简单:

class TestAlert:
    def __init__(self):
        self.message = None
    def notify(self, message):
        self.message = message

然后,您可以通过传递Testalert类的实例来测试您的功能,并通过访问message属性来检查记录的输出。此代码将无法访问任何第三方服务。

def test_sync_check():
    alert = TestAlert()
    sync_check(alert)
    assert alert.message == 'in sync'

相关内容

  • 没有找到相关文章

最新更新