将参数传递给 side_effect 函数以在 unittest.mock 中进行修补
Pass parameter to side_effect function for patching in unittest.mock
我在测试中使用 unittest.mock
中的 patch
来更改远程 API 调用的行为。
我有三个不同的函数,return 三个不同的 json
文件代表要从 API 中 return 编辑的模拟数据。对于每个模拟 api 调用,我将 side_effect
设置为这些函数之一。此模式不是 DRY,但我不知道如何将参数传递给 side_effect
函数。
三个 mock api 调用函数如下所示:
def mock_api_call_1():
with open('path/to/mock_1.json') as f:
mock_data = json.load(f)
return mock_data
这是我的测试
class MyTest(TestCase):
def test_api(self):
with patch('mymodule.utils.api_call', side_effect=mock_api_call_1):
do_crud_operations()
self.assertEqual(MyModel.objects.all().count(), 10)
with patch('mymodule.utils.api_call', side_effect=mock_api_call_2):
do_crud_operations()
self.assertEqual(MyModel.objects.all().count(), 11)
如何重构此代码以便能够将参数传递给 side_effect
(mock_call(1)
而不是 mock_call_1
)。
从 unittest docs,我看到:
side_effect: A function to be called whenever the Mock is called. See
the side_effect attribute. Useful for raising exceptions or
dynamically changing return values. The function is called with the
same arguments as the mock, and unless it returns DEFAULT, the return
value of this function is used as the return value.
我看到传递给 side_effect
的函数采用与 mock 相同的参数,但我仍然不确定如何最好地使用 mock 来完成此操作。我最终会想要添加更多测试用例,所以我不想硬编码不同的 mock_api_call
函数。
我认为最简单的方法是将 side_effect
设置为 returns 一个函数。
def mock_call(num):
def wrapper():
with open("path/to/mock_{num}.json") as f:
data = json.load(f)
return data
return wrapper
现在我可以将 mock_call(1)
传递给 side_effect
,它会按预期运行。
使用 lambda 函数:
from unittest import TestCase, main
from unittest.mock import Mock, patch
import sys
def mock_api_call(x):
print(x)
class MyTest(TestCase):
def test_api(self):
with patch('sys.exit',
side_effect=lambda x: mock_api_call(x)) as m:
m(0)
sys.exit(0)
m(1)
sys.exit(1)
if __name__ == '__main__':
main()
我在测试中使用 unittest.mock
中的 patch
来更改远程 API 调用的行为。
我有三个不同的函数,return 三个不同的 json
文件代表要从 API 中 return 编辑的模拟数据。对于每个模拟 api 调用,我将 side_effect
设置为这些函数之一。此模式不是 DRY,但我不知道如何将参数传递给 side_effect
函数。
三个 mock api 调用函数如下所示:
def mock_api_call_1():
with open('path/to/mock_1.json') as f:
mock_data = json.load(f)
return mock_data
这是我的测试
class MyTest(TestCase):
def test_api(self):
with patch('mymodule.utils.api_call', side_effect=mock_api_call_1):
do_crud_operations()
self.assertEqual(MyModel.objects.all().count(), 10)
with patch('mymodule.utils.api_call', side_effect=mock_api_call_2):
do_crud_operations()
self.assertEqual(MyModel.objects.all().count(), 11)
如何重构此代码以便能够将参数传递给 side_effect
(mock_call(1)
而不是 mock_call_1
)。
从 unittest docs,我看到:
side_effect: A function to be called whenever the Mock is called. See the side_effect attribute. Useful for raising exceptions or dynamically changing return values. The function is called with the same arguments as the mock, and unless it returns DEFAULT, the return value of this function is used as the return value.
我看到传递给 side_effect
的函数采用与 mock 相同的参数,但我仍然不确定如何最好地使用 mock 来完成此操作。我最终会想要添加更多测试用例,所以我不想硬编码不同的 mock_api_call
函数。
我认为最简单的方法是将 side_effect
设置为 returns 一个函数。
def mock_call(num):
def wrapper():
with open("path/to/mock_{num}.json") as f:
data = json.load(f)
return data
return wrapper
现在我可以将 mock_call(1)
传递给 side_effect
,它会按预期运行。
使用 lambda 函数:
from unittest import TestCase, main
from unittest.mock import Mock, patch
import sys
def mock_api_call(x):
print(x)
class MyTest(TestCase):
def test_api(self):
with patch('sys.exit',
side_effect=lambda x: mock_api_call(x)) as m:
m(0)
sys.exit(0)
m(1)
sys.exit(1)
if __name__ == '__main__':
main()