首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >内部函数中的模拟缺省参数值

内部函数中的模拟缺省参数值
EN

Stack Overflow用户
提问于 2020-10-09 18:06:55
回答 2查看 274关注 0票数 3

我有以下(简化)代码:

代码语言:javascript
复制
def get_redis()
  return redis_instance


def bar(key, value, redis=get_redis())
  redis.set(key, value)


def foo()
  bar("key", value)

在我的测试中,我希望模拟函数get_redis来返回fakeredis.FakeStrictRedis()的一个实例,所以我执行了以下操作

代码语言:javascript
复制
def test_foo(mocker):
  mocker.patch("app.main.get_redis", return_value=fakeredis.FakeStrictRedis())
  foo()

模拟的函数没有效果,foo函数试图使用main中的get_redis函数连接到真正的redis。

如果我这样写的话

代码语言:javascript
复制
def bar(key, value)
  redis=get_redis()
  redis.set(key, value)

这是可行的,但我可以将redis作为默认值传递。我怎么能嘲笑?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-10-12 04:31:38

我只需按以下方式稍微修改bar函数,以便在应用模拟之前不会调用您的函数:

代码语言:javascript
复制
def bar(key, value, redis=get_redis)
    if callable(redis):
        redis = redis()
    redis.set(key, value)

用这种方式编写函数意味着在调用函数时将应用模拟,而不是在应用任何模拟之前在启动时应用。简而言之,以这种方式编写bar,可以确保每次调用get_redis函数时,它都会通过您的bar函数进行传播。

票数 2
EN

Stack Overflow用户

发布于 2020-10-16 20:51:08

模拟没有什么问题,但您似乎误解了默认参数值是如何工作的。正如在Python语言引用中解释的那样,默认值是在函数 definition 执行时计算的。

在您的示例中,这意味着在定义get_redis时已经调用了原始bar

代码语言:javascript
复制
def bar(key, value, redis=get_redis()):

这个语句是在pytest导入模块时执行的,即在执行test_foo之前,所以在测试中模拟get_redis没有效果,因为到那时已经太晚了。

若要使默认的供应工厂函数可模拟,请使用None作为默认值,并使函数调用工厂,除非在调用中指定了另一个值:

代码语言:javascript
复制
def bar(key, value, redis=None)
  redis = redis or get_redis()
  redis.set(key, value)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64285172

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档