我正试图弄清楚如何为一个函数创建单元测试,该行为基于第三方服务。
假设这样的函数:
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和else分支,但这取决于第三方服务。
我想到的第一件事是创建一个假的Web服务器并指向该服务器(更改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')
我不太喜欢。
我是否缺少解决此问题的设计?
答案 0 :(得分:0)
签出plotly来测试依赖于第三方服务的代码,而不必像示例中那样检查您是否以测试模式运行。基本思想是使松弛警报服务成为函数的参数,因此对于单元测试,您可以使用伪造的服务,该伪造的服务以您希望的方式执行每次测试。
您的代码最终看起来像这样:
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'