Python单元测试中的易变值字典?
我需要为一个返回字典的函数写单元测试。这个字典里的一个值是 datetime.datetime.now()
,这个值在每次测试运行时都会变化。
我想在我的断言中完全忽略这个键。目前我有一个字典比较的函数,但我真的想像这样使用 assertEqual:
def my_func(self):
return {'monkey_head_count': 3, 'monkey_creation': datetime.datetime.now()}
... unit tests
class MonkeyTester(unittest.TestCase):
def test_myfunc(self):
self.assertEqual(my_func(), {'monkey_head_count': 3}) # I want to ignore the timestamp!
有没有什么好的方法或者优雅的解决方案来做到这一点?我知道 assertAlmostEqual()
,但我记得那只是对浮点数有用。
1 个回答
9
在进行比较之前,先把字典里的时间戳删掉:
class MonkeyTester(unittest.TestCase):
def test_myfunc(self):
without_timestamp = my_func()
del without_timestamp["monkey_creation"]
self.assertEqual(without_timestamp, {'monkey_head_count': 3})
如果你经常需要进行一些和时间相关的测试,比如用到 datetime.now()
,那么你可以对 datetime 类进行一些修改,以便在单元测试中使用。想想这个方法:
import datetime
constant_now = datetime.datetime(2009,8,7,6,5,4)
old_datetime_class = datetime.datetime
class new_datetime(datetime.datetime):
@staticmethod
def now():
return constant_now
datetime.datetime = new_datetime
这样每次在你的单元测试中调用 datetime.datetime.now()
时,它都会返回一个固定的时间戳 constant_now
。如果你想要恢复到原来的 datetime.datetime.now()
,你只需要简单地执行:
datetime.datetime = old_datetime_class
这样一来,一切就会恢复正常。虽然这种方法很有用,但在你给出的简单例子中,我建议在比较之前直接把字典里的时间戳删掉。