如何为使用datetime的时间戳计算函数编写正确的单元测试
单元测试问题排查与修正方案
原测试代码存在的问题
- mock返回值赋值不合法:你给
mock_datetime.now.return_value和mock_timedelta.return_value赋值的是时间格式的字面量,不是Python可识别的datetime、timedelta实例,运行会直接报错 - mock冗余:timedelta的计算逻辑是固定的
days=100*365,不需要额外mock,只需要mock datetime.now的返回值即可完成测试 - 预期值计算逻辑冗余:不需要通过mock对象的返回值二次推导预期值,直接用固定时间计算结果即可,测试用例更清晰
- 注意mock调用参数匹配:原函数调用
datetime.now时传入了timezone.utc参数,mock时要确保参数匹配,否则返回值不会按预期生效
修正后的最简测试代码
from datetime import datetime, timedelta, timezone from unittest.mock import patch @patch("src.shared.utils.datetime") def test_get_timestamp_now_plus_100_years(self, mock_datetime): # 构造固定的当前UTC时间作为mock返回值 fixed_now = datetime(2021, 9, 14, 15, 54, 25, 284087, tzinfo=timezone.utc) mock_datetime.now.return_value = fixed_now # 直接计算预期结果 expected = int((fixed_now + timedelta(days=100*365)).timestamp()) # 断言结果匹配 self.assertEqual(get_timestamp_plus_100_year(), expected)
如需验证timedelta调用参数的测试版本
如果要额外验证函数是否正确传入了days=100*365参数,可以保留timedelta的mock,注意@patch装饰器的参数顺序是从下往上对应函数参数,和你原代码的参数顺序保持一致即可:
@patch("src.shared.utils.timedelta") @patch("src.shared.utils.datetime") def test_get_timestamp_now_plus_100_years(self, mock_datetime, mock_timedelta): fixed_now = datetime(2021, 9, 14, 15, 54, 25, 284087, tzinfo=timezone.utc) mock_datetime.now.return_value = fixed_now fixed_delta = timedelta(days=36500) mock_timedelta.return_value = fixed_delta # 验证timedelta调用参数是否符合预期 mock_timedelta.assert_called_once_with(days=100*365) expected = int((fixed_now + fixed_delta).timestamp()) self.assertEqual(get_timestamp_plus_100_year(), expected)
内容的提问来源于stack exchange,提问作者Giuseppe Fantoni
相关产品推荐
相关产品推荐

