我有一个返回布尔值的函数列表. 它的名字都是这样的:

for f in functions:
    if f():
        pass

我正在编写测试,我想模拟这些函数的结果

@pytest.fixture
def is_first_func_mock(mocker):
    mock = mocker.patch.object(SomeClass, 'first_func')
    return mock

然后在测试中的某个地方,我通过了这一测试,并写道 is_first_func_mock.return_value = True或更多

但是,由于我没有直接在代码中调用函数,而且我在上面已经指出了这一点,所以mock不起作用.

我在Stackoverflow中找到了一个解决方案: 我可以像这样调用函数:

if getattr(funcs_module, func.__name__)():
    pass

但我不喜欢它,我不想改变循环

最新情况:

def some_name(fucntions: list[callable]):
    def inner(func):
        @wraps(func)
        async def wrapper(*args, **kwargs):
            #some code
            for f in functions:
                if f():
                    return await func(*args, **kwargs)
            raise SomePermission

        return wrapper

    return inner

推荐答案

我还没能找到解决方案,但这里有一个变通办法:

from functools import wraps

def has_any_permissions(get_functions):
    def inner(func):
        @wraps(func)
        async def wrapper(*args, **kwargs):
            # some code
            funcs = get_functions()
            if any(f() for f in funcs):
                return await func(*args, **kwargs)
            raise SomePermission()

        return wrapper
    return inner

def is_admin():
    return False

def is_users_moderator():
    return False

def admin_and_users_moderator():
    return [is_admin, is_users_moderator]

@has_any_permissions(admin_and_users_moderator)
def about_user():
    return 'user'   # just for demonstration purposes

我不得不引入一些间接的方法,在这种情况下,修饰器不在装饰时绑定实际的函数列表,而是提供一个函数,当在wrapper()内调用该函数时,每次可以调用目标时都会获得这些函数.

相应的单元测试可能如下所示:

import unittest
from unittest.mock import patch

from mockable_functions import about_user

class Test(unittest.TestCase):
    def test_plain_function_raises(self):
        self.assertRaises(SomePermission, about_user)

    @patch('mockable_functions.is_admin')
    def test_func(self, is_admin_mock):
        is_admin_mock.return_value = True
        self.assertEqual(about_user(), 'user', 'about_user returns user')

此单元测试显示,about_user()在正常调用时会引发错误,但当修补is_admin函数时,实际函数将被调用(并返回一个伪值)

Python相关问答推荐

如何处理必须存在于环境中但无法安装的Python项目依赖项?

使用多个性能指标执行循环特征消除

实现的差异取决于计算出的表达是直接返回还是首先存储在变量中然后返回

替换字符串中的多个重叠子字符串

时间序列分解

Python上的Instagram API:缺少client_id参数"

对整个 pyramid 进行分组与对 pyramid 列子集进行分组

图像 pyramid .难以创建所需的合成图像

numpy卷积与有效

无法在Docker内部运行Python的Matlab SDK模块,但本地没有问题

改进大型数据集的框架性能

字符串合并语法在哪里记录

从嵌套的yaml创建一个嵌套字符串,后面跟着点

幂集,其中每个元素可以是正或负""""

下三角形掩码与seaborn clustermap bug

在Python中使用yaml渲染(多行字符串)

基于另一列的GROUP-BY聚合将列添加到Polars LazyFrame

为什么我的sundaram筛这么低效

Polars map_使用多处理对UDF进行批处理

我什么时候应该使用帆布和标签?