Python单元测试中具有volatile值的字典?

时间:2009-06-26 14:49:52

标签: python unit-testing

我需要为返回字典的函数编写单元测试。这本词典中的一个值是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(),但这只对浮动iirc有用。

1 个答案:

答案 0 :(得分:9)

在进行比较之前,只需从dict中删除时间戳:

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()的与时间相关的测试,那么您可以为您的单元测试进行monkeypatch 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

事情会恢复正常。这种事情很有用,但在你给出的简单例子中,我建议你在比较之前从dict中删除时间戳。