Python 如何在一个文件中模拟datetime?

Python 如何在一个文件中模拟datetime?,python,mocking,Python,Mocking,我有两个使用datetime的文件。有没有办法只在一个文件而不是另一个文件中模拟它?下面是一个我看到奇怪行为的例子 文件:测试文件\u one.py import datetime as dt def print_datetime(): print 'First: {}'.format(dt.datetime.utcnow()) import datetime as dt def print_datetime(): print 'Second: {}'.format(dt.da

我有两个使用
datetime
的文件。有没有办法只在一个文件而不是另一个文件中模拟它?下面是一个我看到奇怪行为的例子

文件:测试文件\u one.py

import datetime as dt
def print_datetime():
    print 'First: {}'.format(dt.datetime.utcnow())
import datetime as dt
def print_datetime():
    print 'Second: {}'.format(dt.datetime.utcnow())
import test_file_one as first
import test_file_two as second
import mock
from datetime import datetime, timedelta

@mock.patch('test_file_one.dt.datetime')
def main(mock_datetime):
    mock_datetime.utcnow.return_value = datetime.utcnow() + timedelta(days=1)
    first.print_datetime()
    second.print_datetime()

if __name__ == '__main__':
    main()
文件:测试文件\u two.py

import datetime as dt
def print_datetime():
    print 'First: {}'.format(dt.datetime.utcnow())
import datetime as dt
def print_datetime():
    print 'Second: {}'.format(dt.datetime.utcnow())
import test_file_one as first
import test_file_two as second
import mock
from datetime import datetime, timedelta

@mock.patch('test_file_one.dt.datetime')
def main(mock_datetime):
    mock_datetime.utcnow.return_value = datetime.utcnow() + timedelta(days=1)
    first.print_datetime()
    second.print_datetime()

if __name__ == '__main__':
    main()
文件:main.py

import datetime as dt
def print_datetime():
    print 'First: {}'.format(dt.datetime.utcnow())
import datetime as dt
def print_datetime():
    print 'Second: {}'.format(dt.datetime.utcnow())
import test_file_one as first
import test_file_two as second
import mock
from datetime import datetime, timedelta

@mock.patch('test_file_one.dt.datetime')
def main(mock_datetime):
    mock_datetime.utcnow.return_value = datetime.utcnow() + timedelta(days=1)
    first.print_datetime()
    second.print_datetime()

if __name__ == '__main__':
    main()
输出

First: 2018-06-12 08:12:43.838243
Second: 2018-06-12 08:12:43.838243
正如您所看到的,两者都返回被模拟的相同日期时间

  • 为什么两个人都被嘲笑
  • 如何将模拟限制为仅一个文件

  • 我建议你减少嘲弄的范围

    现在,通过使用decorator
    @mock.patch('test\u file\u one.dt.datetime')

    相反,您可以尝试以下方法:

    def main(mock_datetime):
        with mock.patch('test_file_one.dt.datetime') as mock_datetime:
            mock_datetime.utcnow.return_value = datetime.utcnow() + timedelta(days=1)
            first.print_datetime()
    
        second.print_datetime()
    
    from libfaketime_tz_wrapper import fake_time
    
    def main(mock_datetime):
        with fake_time(datetime.utcnow() + timedelta(days=1)):
            first.print_datetime()
    
        second.print_datetime()
    
    或者,您可以使用
    libfaketimetz包装器
    库中的
    fake_-time
    方法

    那么您的方法将类似于:

    def main(mock_datetime):
        with mock.patch('test_file_one.dt.datetime') as mock_datetime:
            mock_datetime.utcnow.return_value = datetime.utcnow() + timedelta(days=1)
            first.print_datetime()
    
        second.print_datetime()
    
    from libfaketime_tz_wrapper import fake_time
    
    def main(mock_datetime):
        with fake_time(datetime.utcnow() + timedelta(days=1)):
            first.print_datetime()
    
        second.print_datetime()
    

    我没有测试我的建议是否有效,但在过去的1,5年中,我一直在大量使用
    fake\u time
    ,在类似的问题上似乎非常少见。

    你只需添加你想要添加的结果即可


    谢谢你的回答<代码>假时间看起来很有趣。在实际场景中,缩小范围并不总是可能的。例如,如果第一个文件中的方法调用第二个文件中的方法(我仍然希望仅在第一个文件中模拟datetime),则缩小范围不起作用(使用
    mock
    fake\u time
    )。在这种情况下,你会怎么做?我觉得问题在于
    mock
    库是如何工作的。当我模拟一个文件时,它不应该在另一个文件中模拟(我猜)。我希望
    mock
    更加明确,也就是说,只在我明确提到的文件中进行mock。事实上,有时我们不能缩小范围,但这不是有点代码味道吗?模拟库的工作方式是将该上下文下的所有内容包装到模拟中定义的参数和值中。所以,如果您为一个文件模拟某个内容,范围将保持模拟状态,直到它结束或另一个模拟到位。也许重写方法以更好地分离关注点?我不一定在所有情况下都能看出它的代码味道。特别是在使用外部库时。假设您有一个函数,它获取
    utcnow
    ,然后构造一个对象(从外部库,比如
    Schematics
    )。底层库可以很好地执行类似于
    isinstance(d,datetime)
    的类型检查。现在,在我的方法中模拟
    datetime
    ,也会影响基础库功能。@Siddharth使用功能怎么样?谢谢!我从来不知道你能做到这一点。