模拟datetime.now的Fudge
我想用一个叫做 mock 的库,来替换 datetime.now()
的结果,以便测试一些逻辑。所以我现在在用 mocker
,效果不错,但我遇到了一些问题,可能是bug,所以我想换个更新的工具。谷歌建议我使用 fudge
,但是我没办法让它替换 datetime.now()
。
from one import ClassName
def test_fudge():
import fudge
@fudge.patch('datetime.datetime.now')
def a(dtn):
dtn.expects_call().returns(1)
print 'fudge:', 'yep' if ClassName().one() == 1 else 'nope'
a()
test_fudge()
这是一个名为 one.py 的文件:
from datetime import datetime, timedelta
class ClassName(object):
def one(self):
return datetime.now()
结果是: fudge: nope
有没有什么想法?
mocker 的例子:
import mocker
from one import ClassName
m = mocker.Mocker()
n = m.replace('datetime.datetime')
n.now()
m.result(123)
with m:
print ClassName().one()
one.py 是一样的。
结果:123
1 个回答
3
这个问题是因为你在 one.py 中导入 datetime
模块的方式造成的。你可以试试这样做:
import datetime
class ClassName(object):
def one(self):
return datetime.datetime.now()
这个问题是由于 Python 导入的方式引起的。如果你使用其他的模拟库,比如 mock
,也会遇到同样的问题。
我会尽量解释清楚,但在 StackOverflow 上有更好的答案,只是我没找到我想要的那个。
当你使用 from datetime import datetime
时,datetime
包被导入,并且 datetime.datetime
类的引用在 one.py 的本地范围内被绑定。
不过,fudge 被赋予的名字是 datetime.datetime.now()
,这个名字和 one.py 中的本地绑定是不同的,所以没有进行补丁处理。
test_fudge() 运行时,它想要修补名字 datetime.datetime.now
,那么它怎么知道 one.py 中的 datetime
名字在运行时指向的是和 datetime.datetime
相同的对象呢?