模拟datetime.now的Fudge

1 投票
1 回答
540 浏览
提问于 2025-04-17 13:20

我想用一个叫做 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 相同的对象呢?

撰写回答