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使用功能怎么样?谢谢!我从来不知道你能做到这一点。