我创建了一个函数,该函数返回该时间下一次出现之前的秒数,但是我在为它编写单元测试时遇到了问题。人们如何测试这种调用datetime.now()
的函数?
添加另一个参数(current_time
(似乎只是为了测试它,因为它改变了函数的初始要求。
要测试的函数是。
from datetime import datetime, time, timedelta
def get_time_left(target_time):
'''return float of number of seconds left until the target_time'''
if not isinstance( target_time, time ):
raise TypeError("target_time must be datetime.time")
curr_time = datetime.now()
target_datetime = datetime.combine( datetime.today(), target_time )
if curr_time > target_datetime:
target_datetime = curr_time + timedelta(1)
seconds_left = (curr_time - target_datetime).total_seconds()
return seconds_left
对它的考验是。
class TestDTime(unittest.TestCase):
def test_time_left(self):
dt_now = datetime.now()
tm_5sec_future = ( dt_now + timedelta(0,5) ).time()
self.assertEqual( dtime.get_time_left(tm_5sec_future), 5.0)
结果是。
======================================================================
FAIL: test_time_left (__main__.TestDTime)
----------------------------------------------------------------------
Traceback (most recent call last):
File "tests/ctatest.py", line 37, in test_time_left
self.assertEqual( dtime.get_time_left(tm_5sec_future), 5.0)
AssertionError: -4.999985 != 5.0
在不向函数添加任何参数的情况下对这样的东西进行单元测试的最佳方法是什么?
您需要使用模拟框架将 UT 与依赖项隔离,以便您的 UT 具有一致性行为。
Freezegun - 是一个很好的嘲笑库,因为我被使用过。
只需安装此库:pip install freezegun
在您的UT中使用装饰器@freeze_time
如下:
@freeze_time("2018-06-03")
def test_time_left(self):
dt_now = datetime.now()
tm_5sec_future = (dt_now + timedelta(0, 5)).time()
self.assertEqual(dtime.get_time_left(tm_5sec_future), -5.0)