Mock测试【免费下载链接】motoA library that allows you to easily mock out tests based on AWS infrastructure.项目地址https://gitcode.com/gh_mirrors/mo/moto点击查看免费下载本篇技术指南聚焦 Moto 对 AWSAccount服务account的模拟实现。AWS Account 服务用于管理账户级别的信息其中与日常测试最相关的是备用联系人Alternate Contact的增删查操作。读完本文你将掌握如何在基于boto3的测试中使用 Moto 的mock_aws装饰器模拟PutAlternateContact、GetAlternateContact、DeleteAlternateContact三个 API并理解其底层数据模型、异常语义与多账户隔离的实现原理。一、官方文档Account 服务实现清单Moto 官方文档docs/docs/services/account.rst维护了一份该服务的能力清单逐条列出 AWS Account API 是否已被模拟API 名称状态accept_primary_email_update未实现delete_alternate_contact✅ 已实现disable_region未实现enable_region未实现get_account_information未实现get_alternate_contact✅ 已实现get_contact_information未实现get_gov_cloud_account_information未实现get_primary_email未实现get_primary_email_update_status未实现get_region_opt_status未实现list_regions未实现put_account_name未实现put_alternate_contact✅ 已实现put_contact_information未实现start_primary_email_update未实现可以看到Moto 目前只实现了与Alternate Contact备用联系人相关的三个操作。其余诸如账户邮箱变更、区域开关region opt-in/out、联系信息维护、账户名称设置等能力均不在当前模拟范围内——在编写相关测试时若调用这些 APIMoto 会返回未实现/不支持的错误。同样的清单也会同步呈现在仓库根目录的 IMPLEMENTATION_COVERAGE.md 中## account一节与官方文档保持一致可作为测试规划时的快速参考。二、源码结构总览Moto 的 Account 服务实现位于 moto/account 目录遵循 Moto 一贯的模型—响应—路由三层结构models.py定义AlternateContact数据模型与AccountBackend后端存放内存中的备用联系人数据responses.pyAccountResponse负责解析 HTTP 请求参数、调用后端方法并组装返回结果urls.py定义 URL 路由将三个 API 端点映射到AccountResponse.dispatchexceptions.py定义UnknownContactType与UnspecifiedContactType两个异常__init__.py导出account_backends供 Moto 全局后端索引注册。该服务通过 backend_index.py 中的正则https?://account\.(.)\.amazonaws\.com注册到 Moto 的 URL 分发器因此boto3.client(account)发出的请求会被正确拦截并路由到上述处理逻辑。三、数据模型与后端内存中的备用联系人存储3.1 AlternateContact 模型在 models.py 中备用联系人被定义为一个dataclassdataclass class AlternateContact(BaseModel): alternate_contact_type: str title: str name: str email_address: str phone_number: str五个字段与 AWSPutAlternateContactAPI 的请求参数一一对应。此外models.py 还定义了一个关键常量ALLOWED_CONTACT_TYPES [SECURITY, OPERATIONS, BILLING]这决定了 Moto 只接受SECURITY、OPERATIONS、BILLING三种合法的备用联系人类型与真实 AWS 的约束一致。3.2 AccountBackend 的实现AccountBackendmodels.py以字典_alternate_contacts: dict[str, AlternateContact]按联系人类型缓存数据并实现三个核心方法put_alternate_contact(...)按类型写入覆盖一条备用联系人记录get_alternate_contact(type)按类型读取若不存在则抛出UnspecifiedContactTypedelete_alternate_contact(type)按类型删除使用pop(type, None)删除不存在的类型不会报错幂等删除。注意后端实例的注册方式account_backends BackendDict( AccountBackend, account, use_boto3_regionsFalse, additional_regionsPARTITION_NAMES, )这里use_boto3_regionsFalse表示不依赖 boto3 的真实区域列表additional_regionsPARTITION_NAMES则说明后端按 AWS分区partition如aws、aws-cn、aws-us-gov等定义于 moto/utilities/utils.py而非具体区域来划分。这意味着 Account 服务的数据是分区级隔离的而非区域级隔离。3.3 多账户隔离响应层在存取数据前会先解析目标账户def _get_account_id(self) - str: return self._get_param(AccountId) or self.current_accountresponses.py当请求中携带AccountId参数管理账户代成员账户操作备用联系人的场景时使用该值否则回退到当前请求的账户。随后通过account_backends[account_id][self.partition]取到对应账户分区的独立后端实例实现了不同账户之间备用联系人数据互不可见的隔离语义。四、URL 路由与请求分发urls.py 中定义了路由规则url_bases [ rhttps?://account\.(.)\.amazonaws\.com, ] url_paths { {0}/putAlternateContact$: AccountResponse.dispatch, {0}/getAlternateContact$: AccountResponse.dispatch, {0}/deleteAlternateContact$: AccountResponse.dispatch, }三个操作均经由AccountResponse.dispatch统一分发再由AccountResponse中的同名方法根据 HTTP 动作ACTION完成参数解析与调用。AccountResponse在__init__中声明service_nameaccountresponses.py从而复用 Moto 核心的响应处理基础设施。五、实战用 mock_aws 模拟备用联系人 API下面基于 Moto 自带的测试tests/test_account/test_account_alternate_contacts.py展示完整可运行的用法。5.1 写入并读取备用联系人import boto3 from moto import mock_aws mock_aws def test_put_alternate_contact(): client boto3.client(account, region_nameap-southeast-1) # 写入当前账户的 SECURITY 备用联系人 client.put_alternate_contact( AlternateContactTypeSECURITY, EmailAddresstesttest.com, NameTest Test, PhoneNumber000000000000, TitleDr. Test, ) # 读取并校验 details client.get_alternate_contact(AlternateContactTypeSECURITY)[ AlternateContact ] assert details[AlternateContactType] SECURITY assert details[Title] Dr. Test assert details[Name] Test Test assert details[EmailAddress] testtest.com assert details[PhoneNumber] 000000000000要点使用mock_aws装饰器包裹测试函数装饰器可作用于函数、类或 pytest fixture参考 tests/conftest.py 中的通用配置boto3.client(account, region_name...)可指定任意区域因为后端是分区级存储put_alternate_contact的成功响应无返回体get_alternate_contact返回{AlternateContact: {...}}结构五个字段与模型一一对应。5.2 管理账户操作其他账户的备用联系人AWS 的PutAlternateContact/GetAlternateContact支持通过AccountId参数指定目标账户。Moto 同样支持这一语义且数据按账户隔离mock_aws def test_alternate_contact_multi_account(): client boto3.client(account, region_nameap-southeast-1) # 当前账户写入 client.put_alternate_contact( AlternateContactTypeBILLING, EmailAddresstesttest.com, NameTest Test, PhoneNumber000000000000, TitleDr. Test, ) # 为目标账户 111111111111 写入 client.put_alternate_contact( AccountId111111111111, AlternateContactTypeBILLING, EmailAddresstestdiff.com, NameContact in 111111111111, PhoneNumber000000000000, TitleDr. Test, ) # 两账户数据互不干扰 details client.get_alternate_contact(AlternateContactTypeBILLING)[ AlternateContact ] assert details[Name] Test Test details client.get_alternate_contact( AccountId111111111111, AlternateContactTypeBILLING )[AlternateContact] assert details[Name] Contact in 111111111111 assert details[EmailAddress] testdiff.com这正是 responses.py 中_get_account_id逻辑的直接体现。5.3 删除备用联系人mock_aws def test_delete_alternate_contact(): client boto3.client(account, region_nameap-southeast-1) client.put_alternate_contact( AlternateContactTypeSECURITY, EmailAddresstesttest.com, NameTest Test, PhoneNumber000000000000, TitleDr. Test, ) # 删除前可正常读取 client.get_alternate_contact(AlternateContactTypeSECURITY) # 删除 client.delete_alternate_contact(AlternateContactTypeSECURITY) # 删除后再读取将抛出 ResourceNotFoundException with pytest.raises(ClientError) as exc: client.get_alternate_contact(AlternateContactTypeSECURITY) err exc.value.response[Error] assert err[Code] ResourceNotFoundException注意由于后端使用pop(type, None)对不存在的类型执行删除不会报错这与 AWS 行为一致适合幂等清理场景。六、异常语义与错误码Moto 在 exceptions.py 中定义了两种异常且测试用例对其有完整断言6.1 UnknownContactType非法联系人类型当AlternateContactType不在ALLOWED_CONTACT_TYPES中时响应层responses.py会借助 STS 服务解析当前调用者的 ARN并抛出class UnknownContactType(JsonRESTError): def __init__(self, user_arn: str, action: str): message fUser: {user_arn} is not authorized to perform: account:{action} (You specified an invalid Alternate Contact type.) super().__init__(error_typeAccessDeniedException, messagemessage)对应的错误表现为Error Code: AccessDeniedException Message: User: caller_arn is not authorized to perform: account:GetAlternateContact (You specified an invalid Alternate Contact type.)该异常由测试 test_get_unspecified_alternate_contact 覆盖验证。注意这里会动态调用sts_backend.get_caller_identitymoto/sts/models.py因此使用 Moto 的 STS 模拟是该项异常语义工作的前提。6.2 UnspecifiedContactType联系人不存在当指定类型的备用联系人尚未写入时get_alternate_contact抛出class UnspecifiedContactType(JsonRESTError): def __init__(self) - None: super().__init__( error_typeResourceNotFoundException, messageNo contact of the inputted alternate contact type found., )对应的错误表现为Error Code: ResourceNotFoundException Message: No contact of the inputted alternate contact type found.该异常由测试 test_get_unknown_alternate_contact 覆盖验证。七、服务级行为总结行为维度Moto 实现依据合法联系人类型SECURITY/OPERATIONS/BILLINGmodels.py数据存储粒度按 账户 分区partition隔离models.py多账户支持支持AccountId参数指定目标账户responses.py非法类型错误AccessDeniedException需 STS 配合exceptions.py读取不存在联系人ResourceNotFoundExceptionexceptions.py删除不存在联系人静默成功幂等models.py已实现 APIPutAlternateContact/GetAlternateContact/DeleteAlternateContactdocs/docs/services/account.rst从源码结构看Moto 对 Account 服务的实现聚焦于备用联系人这一小而有用的场景非常适合用于测试账户资料补全校验、多账户权限/数据隔离逻辑、以及联系人缺失时抛出ResourceNotFoundException这类错误路径的单元测试。若你的测试还涉及区域启用、主邮箱变更等能力则需要等待 Moto 后续版本补齐或考虑直接对真实 AWS 进行集成测试。相关资源官方实现清单docs/docs/services/account.rst实现覆盖总表IMPLEMENTATION_COVERAGE.md服务后端与模型moto/account/models.py请求响应层moto/account/responses.pyURL 路由moto/account/urls.py异常定义moto/account/exceptions.py测试用例tests/test_account/test_account_alternate_contacts.py赞分享Mock测试【免费下载链接】motoA library that allows you to easily mock out tests based on AWS infrastructure.项目地址https://gitcode.com/gh_mirrors/mo/moto点击查看免费下载相关推荐moto 中 AWS DevOps Agentdevops-agent服务的 Mock 支持已实现操作、使用方式与源码实现解析moto 中 AWS DevOps Agentdevops agent服务的 Mock 支持已实现操作、使用方式与源码实现解析 本篇以 moto 仓库中Mock测试moto 中 connectcampaigns 服务的实现用 mock_aws 模拟 AWS Connect Contact Lens Campaign 的测试实践moto 中 connectcampaigns 服务的实现用 mock_aws 模拟 AWS Connect Contact Lens Campaign 的测Mock测试moto 中 AWS Config 服务的实现全解已支持 API、Recorder/Aggregator 机制与源码级剖析moto 中 AWS Config 服务的实现全解已支持 API、Recorder/Aggregator 机制与源码级剖析 本文以 docs/docs/serMock测试上一篇如何一次搞定 BabelDOC 高级功能兼容性排障、本地模型接入与术语一致性 4 组命令解决下一篇LMFlow Function-Call Finetune 实战指南基于工具对话模板微调大模型创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考