我正在尝试在自定义 ansible 模块上创建一些 pytest 单元测试。我正在尝试模拟 boto3 客户端并测试该类的逻辑。 我将 boto 的初始化移至类方法中,以便我可以修补该类并将其替换为模拟对象。
补丁似乎成功了,“_init_boto”方法返回一个模拟对象。 但我不知道如何设置返回值,以便“describe_stacks(..)”返回自定义响应,或对模拟上的调用进行断言。 示例代码:
cf_stack_exists.py:
import boto3
class CfStackExistsSimplified:
def __init__(self, aws_profile) -> None:
super().__init__()
self.aws_profile = aws_profile
self.boto_client = self._init_boto(aws_profile)
def _init_boto(self):
session = boto3.session.Session(profile_name=self.aws_profile)
return session.client('cloudformation')
def exec(self):
response = self.boto_client.describe_stacks(
StackName=self.aws_profile
)
return response
test_myclass.py:
from unittest.mock import patch
from cf_stack_exists import CfStackExistsSimplified
class TestCfStackExists:
@patch.object(CfStackExistsSimplified, "_init_boto")
def test_example(self, mock_init_boto):
myclass = CfStackExistsSimplified(aws_profile="dev")
response = myclass.exec()
print(f"\n{mock_init_boto.mock_calls}\n")
mock_init_boto.describe_stacks().assert_called()
当我运行它时,它失败并出现错误:
...
> raise AssertionError(msg)
E AssertionError: Expected 'mock' to have been called.
...
但是打印语句显示它已被调用?
[call('dev'), call().describe_stacks(StackName='dev')]
我真的不知道如何断言这个模拟,尝试了很多不同的断言命令。非常感谢任何帮助!!
通过在模拟函数对象后面放置括号,您将再次调用该函数,获取模拟调用返回的子
Mock
对象,而不是具有调用记录的模拟函数对象。
要断言调用了模拟函数,请调用模拟函数对象本身的
assert_called
方法。
改变:
mock_init_boto.describe_stacks().assert_called()
至:
mock_init_boto.describe_stacks.assert_called()