use*_*612 6 python datetime mocking pickle
有没有办法让python pickle忽略"它不是同一个对象"的错误?
我正在使用Mock编写一个测试,对datetime.utcnow()产生的结果进行细粒度控制.我正在使用的代码是时间敏感的,因此mock的补丁使其易于测试.
相同的测试需要pickle对象并将结果发送到远程服务器.为了测试的目的,如果远程服务器腌制和接收标准日期时间,一切都会好的.
不幸的是,pickle模块正在发生以下错误:
无法pickle <type'datetime.datetime'>:它与datetime.datetime不是同一个对象
这是重现错误的最小示例.
from mock import patch
from datetime import datetime
import pickle
class MockDatetime(datetime):
frozendt = datetime(2011,05,31)
@classmethod
def advance(cls, **kw):
cls.frozendt = cls.frozendt + timedelta(**kw)
@classmethod
def utcnow(cls):
return cls.frozendt
@patch('datetime.datetime', MockDatetime)
def test():
pickle.dumps(datetime.utcnow())
if __name__ == '__main__':
test()
Run Code Online (Sandbox Code Playgroud)
是否有一些组合 __reduce__和__getstate__方法可能会欺骗泡菜机器思考MockDatetime是一个日期时间,当我腌制?
如果有人想要一个通用的解决方案来腌制嘲笑:
m = mock.MagicMock()
m.__reduce__ = lambda self: (mock.MagicMock, ())
Run Code Online (Sandbox Code Playgroud)
请注意,这似乎并没有保存使用的模拟(例如调用)的内部内容。
看一下文档中的补丁部分,我看到了这个建议:
其基本原理是,你修补的一个对象被使用,这是不一定相同的地方,因为它是定义在哪里.
按照这个建议,我试图替换:
@patch('datetime.datetime', MockDatetime)
Run Code Online (Sandbox Code Playgroud)
有:
@patch('__main__.datetime', MockDatetime)
Run Code Online (Sandbox Code Playgroud)
我没有收到任何错误pickle.此外,我添加了一个print声明,以确保它datetime真的被修补,我得到了预期的价值.