关于python:如何覆盖当前时间?

How to override current time?

我正在编写一个利用当前时间的应用程序(通过datetime.datetime.now())

有没有办法,为了调试的目的,覆盖这个调用,以便它返回一个特定的时间戳?

作为一个后备,我可以编写一个函数,它将被调用而不是datetime.datetime.now()并返回所需的任何内容(producton中的实际当前时间和调试时所需的测试时间)但是可能有更多的pythonic方法来执行这些类型的行动?


从广义上讲,您的选择是:

  • 使用unittest.mock库,它可以使用虚函数替换动态函数,该函数始终提供相同的结果(或使用另一个执行相同操作的模拟库)。这意味着您不必修改您的功能;然而,合理的人可能会不同意使用mock进行猴子修补是否是好习惯,即使是调试也是如此。我认为这是Python中使用最广泛的解决方案。
  • 修改您的函数以根据其环境(系统上的实际环境变量,全局状态或其他内容)执行不同的操作。这是最简单的方法,也是最粗糙,最脆弱的方式,因此您必须确保在调试完成后将其更改回来。
  • 修改你的函数以接受函数本身作为参数,并在正常操作中传入datetime.datetime.now作为该函数,但传入不同的东西(例如存根)进行测试。

您可以使用模拟库来模拟datetime.datetime.now()用法:

1
2
3
4
5
6
7
8
import mock

def my_test():
    my_mock = mock.Mock(return_value=your_desired_timestamp)

    with mock.patch('mymodule.datetime.datetime.now', my_mock):
        # Here, all calls to `datetime.datetime.now` referenced by `datetime.datetime`
        # defined in `my_module` will be mocked to return `your_desired_timestamp`.