gpt4 book ai didi

用模拟函数替换真实返回值和函数实现的 Pythonic 方法

转载 作者:太空狗 更新时间:2023-10-30 03:02:22 26 4
gpt4 key购买 nike

我的 flask+python 应用程序通过第三方模块 nativelib 从 native 二进制文件中提取 json。

基本上,我的函数看起来像这样

def list_users():
return nativelib.all_users()

然而,事实证明,对这个第三方模块的强烈依赖和庞大的 native 组件是快速开发的巨大障碍。

我想做的是模拟我的 list_users 函数的返回值。此外,我应该能够通过简单地切换一些 bool 值来切换回“真实数据”。这个 bool 值可以是代码中的某个属性或某个命令行参数。

我目前设计的解决方案看起来像这样:

@mockable('users_list')
def list_users():
return nativelib.all_users()

我已经将上述 mockable 实现为一个类:

class mockable:
mock = False

# A dictionary that contains a mapping between the api method
# ..and the file which contains corresponding the mock json response
__mock_json_resps = {'users_list':'/var/mock/list_user.json', 'user_by_id': '/var/mock/user_1.json'}

def __init__(self, api_method):
self.api_method = api_method

def __call__(self, fn):
@wraps(fn)
def wrapper():
if mock:
# If mocking is enabled,read mock data from json file
mock_resp = __mock_json_resps[self.api_method]
with open(mock_resp) as json_file:
return json.load(json_file)
else:
return self.fn()

return wrapper

在我的入口点模块中,我可以使用

mockable.mock = True

现在虽然这可能有效,但我很想知道这是否是“pythonic”方式。

如果没有,实现这一目标的最佳方法是什么?

最佳答案

就我个人而言,我更喜欢使用 mock 库,尽管它是一个额外的依赖项。此外,模拟仅在我的单元测试中使用,因此实际代码不会与测试代码混合。因此,在您的位置,我将保留您拥有的功能:

def list_users():
return nativelib.all_users()

然后在我的单元测试中,我会“临时”修补 native 库:

def test_list_users(self):
with mock.patch.object(nativelib,
'all_users',
return_value='json_data_here')):
result = list_users()
self.assertEqual(result, 'expected_result')

此外,为了编写多个测试,我通常将模拟代码变成装饰器,例如:

def mock_native_all_users(return_value):
def _mock_native_all_users(func):
def __mock_native_all_users(self, *args, **kwargs):
with mock.patch.object(nativelib,
'all_users',
return_value=return_value):
return func(self, *args, **kwargs)
return __mock_native_all_users
return _mock_native_all_users

然后使用它:

@mock_native_all_users('json_data_to_return')
def test_list_users(self):
result = list_users()
self.assertEqual(result, 'expected_result')

关于用模拟函数替换真实返回值和函数实现的 Pythonic 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22075851/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com