
Mock测试【免费下载链接】motoA library that allows you to easily mock out tests based on AWS infrastructure.项目地址https://gitcode.com/gh_mirrors/mo/moto点击查看免费下载Moto 是一个以内存态方式模拟 AWS 基础设施的测试库其workspaces-web模块为 Amazon WorkSpaces Web 服务提供了可离线运行的 API 实现覆盖 Portal门户、Browser Settings浏览器设置、Network Settings网络设置、User Settings用户设置、User Access Logging Settings用户访问日志设置以及资源标签管理等核心能力。本文以官方服务文档 docs/docs/services/workspaces-web.rst 为主体结合 moto/workspacesweb/models.py、moto/workspacesweb/responses.py 等源码与 tests/test_workspacesweb/test_workspacesweb.py 测试用例系统讲解该模块支持哪些 API、数据模型如何组织、资源如何关联以及如何用mock_aws在单元测试中驱动 boto3 客户端完成完整的创建-查询-关联-删除闭环。WorkSpaces Web 在 Moto 中的定位Amazon WorkSpaces Web 是 AWS 提供的安全远程浏览器服务管理员通过 Portal 向终端用户交付隔离的浏览器会话并借助一系列 Settings 资源网络、浏览器策略、用户权限、日志等控制体验与安全边界。Moto 的workspaces-web模块把这一服务的能力搬进本地进程内存中使 CI 与本地开发无需真实 AWS 账号即可验证集成代码。从后端注册看该服务通过 moto/backends.py 导入WorkSpacesWebBackend并在 moto/backend_index.py 中以正则https?://workspaces-web\.(.)\.amazonaws\.com挂接 URL 前缀URL 路由本身定义在 moto/workspacesweb/urls.py覆盖browserSettings、networkSettings、userSettings、userAccessLoggingSettings、portals、tags六类端点。也就是说只要 boto3 客户端以region_name构造出workspaces-web.{region}.amazonaws.com的请求地址Moto 的响应层即可接管并返回模拟数据。API 覆盖清单已实现与未实现服务文档用勾选框形式逐条列出该服务下全部 API 的实现状态[X]表示已实现[ ]表示尚未实现调用会返回未实现错误或不可用。整体来看已实现的 27 个 API覆盖了五大资源对象的创建、查询、列举、删除与关联以及标签操作未实现的 65 个 API集中在数据保护设置、IP 访问设置、身份提供商、会话日志、信任存储、会话管理及各类资源的 update 与 disassociate 操作。已实现 API[X]分类API关联操作associate_browser_settings、associate_network_settings、associate_user_access_logging_settings、associate_user_settings浏览器设置create_browser_settings、get_browser_settings、list_browser_settings、delete_browser_settings网络设置create_network_settings、get_network_settings、list_network_settings、delete_network_settings用户设置create_user_settings、get_user_settings、list_user_settings、delete_user_settings访问日志设置create_user_access_logging_settings、get_user_access_logging_settings、list_user_access_logging_settings、delete_user_access_logging_settings门户create_portal、get_portal、list_portals、delete_portal标签管理list_tags_for_resource、tag_resource、untag_resource未实现 API[ ]其余操作当前均未在 Moto 中实现包括但不限于设置类资源create/get/update/delete/associate/disassociate_data_protection_settings、ip_access_settings、session_logger、trust_store、identity_provider更新与解绑update_browser_settings、update_network_settings、update_portal、update_user_settings、update_user_access_logging_settings以及全部disassociate_*操作会话与元数据expire_session、get_session、list_sessions、get_portal_service_provider_metadata、list_trust_store_certificates等。编写测试或集成代码前应先核对上表避免对未实现的 API 抱有不切实际的预期这是 Moto 服务文档的核心价值之一——它以机器可读的清单告诉你哪些能用、哪些不能用。架构分层URL → Response → Backend → Modelworkspaces-web模块遵循 Moto 的标准四层架构理解这条调用链有助于排查问题或扩展功能URL 层moto/workspacesweb/urls.py定义 base URL 正则与路径模板例如{0}/portals/(?PportalArn[^/])portal/(?Puuid[^/])$、{0}/portals/(?PportalArn.*)/browserSettings$将 HTTP 方法分派到 moto/workspacesweb/responses.py 中的静态处理器Response 层WorkSpacesWebResponse继承BaseResponse通过workspacesweb_backends[self.current_account][self.region]拿到当前账号 区域对应的后端实例再对请求体做参数提取self._get_param与响应 JSON 序列化Backend 层WorkSpacesWebBackend以SERVICE_NAMESPACE workspaces-web标识内部维护五个内存字典network_settings、browser_settings、user_settings、user_access_logging_settings、portals键均为资源 ARN并持有TaggingService实例负责标签存储Model 层FakePortal、FakeBrowserSettings、FakeNetworkSettings、FakeUserSettings、FakeUserAccessLoggingSettings五个BaseModel子类负责生成资源 ID、格式化 ARN 与序列化to_dict()。后端通过BackendDict(WorkSpacesWebBackend, workspaces-web)注册见 moto/workspacesweb/models.py因此每个 AWS 区域都有独立的状态空间——这与真实 AWS 的区域隔离语义一致也是测试可以并行、互不污染的基础。五大资源模型的字段与返回结构1. Network Settings网络设置由FakeNetworkSettings实现创建时接受securityGroupIds安全组 ID 列表、subnetIds子网 ID 列表、vpcIdVPC ID以及可选的tags。其 ARN 格式为arn:{partition}:workspaces-web:{region}:{account_id}:network-settings/{uuid}partition由 moto/utilities/utils.py 的get_partition(region_name)计算如aws、aws-cn、aws-us-gov。to_dict()返回networkSettingsArn、securityGroupIds、subnetIds、vpcId与associatedPortalArns已关联门户的 ARN 列表。2. Browser Settings浏览器设置FakeBrowserSettings接受additionalEncryptionContext附加加密上下文、browserPolicy浏览器策略、clientToken幂等令牌、customerManagedKey客户管理 KMS 密钥。浏览器设置同样维护associatedPortalArns用于反向追踪哪些门户使用了该设置。3. User Settings用户设置FakeUserSettings是字段最丰富的模型除加密上下文与密钥外还包含一组权限开关与超时参数参数说明默认行为copyAllowed/pasteAllowed/downloadAllowed/uploadAllowed/printAllowed/deepLinkAllowed各项用户操作是否允许未传值时默认DisableddisconnectTimeoutInMinutes断连超时分钟透传原值idleDisconnectTimeoutInMinutes空闲断连超时分钟透传原值cookieSynchronizationConfigurationCookie 同步配置透传原值clientToken幂等令牌透传原值注意一个实现细节Moto 将权限开关保存为字符串Enabled/Disabled见 moto/workspacesweb/models.py与真实 API 的布尔语义在存储层做了归一化测试断言时应匹配字符串值——这也是 tests/test_workspacesweb/test_workspacesweb.py 中断言resp[copyAllowed] Enabled的原因。4. User Access Logging Settings用户访问日志设置FakeUserAccessLoggingSettings接受clientToken与kinesisStreamArnKinesis 数据流 ARN用于把用户访问日志投递到 Kinesis。其 ARN 资源段为user-access-logging-settings/{uuid}。5. Portal门户FakePortal是核心资源创建时接受additionalEncryptionContext、authenticationType如Standard、clientToken、customerManagedKey、displayName、instanceType、maxConcurrentSessions。创建后 Moto 自动填充一系列派生字段portalEndpoint形如{portal_id}.portal.awsbrowserType固定为ChromerendererType固定为AppStreamstatus固定为CREATEDstatusReason固定为TestStatusReasoncreationDate使用datetime.datetime.now().isoformat()。门户还持有七个可关联资源的 ARN 字段browserSettingsArn、networkSettingsArn、trustStoreArn、ipAccessSettingsArn、userAccessLoggingSettingsArn、userSettingsArn初始均为None。关联机制双向记账的 associate 操作Moto 对associate_*的实现采用了双向记账模式每次关联不仅把设置资源的 ARN 写入 Portal 的对应字段还把 Portal ARN 追加到设置资源的associated_portal_arns列表中。以associate_browser_settings为例moto/workspacesweb/models.py从browser_settings与portals字典按 ARN 取出对象browser_settings_object.associated_portal_arns.append(portal_arn)portal_object.browser_settings_arn browser_settings_arn。因此关联完成后从任一侧查询都能得到完整关系get_portal返回的browserSettingsArn已填充get_browser_settings返回的associatedPortalArns则包含该门户。associate_network_settings、associate_user_settings、associate_user_access_logging_settings三个操作逻辑完全同构。测试 tests/test_workspacesweb/test_workspacesweb.py 正是同时断言了这两个方向的字段。从 URL 层看关联操作复用/portals/{portalArn}/xxx子路径见 moto/workspacesweb/urls.py响应层则从请求体读取设置资源 ARN、从 URL 路径中提取 portal ARNself.parsed_url.path.split(/portals/)[-1].split(/browserSettings)[0]。标签管理TaggingService 与 Resource Groups 集成标签能力由WorkSpacesWebBackend持有的TaggingService提供tag_resource(arn, tags)将dict[str, str]形式的标签写入服务响应层先把[{Key, Value}]列表转换为字典moto/workspacesweb/responses.pyuntag_resource(arn, tag_keys)按键名删除标签list_tags_for_resource(arn)返回[{Key, Value}]列表供get/list校验iter_tagged_resources()实现TaggableResourcesMixin以resource_typeworkspaces-web:portal暴露门户资源使resourcegroupstaggingapi服务的get_resources也能索引到这些门户moto/workspacesweb/models.py。标签测试覆盖了五种资源类型的添加 → 追加 → 删除全流程tests/test_workspacesweb/test_workspacesweb.py初始标签、追加新标签后合并返回、按键删除后仅剩剩余标签。实战用 mock_aws 跑通 WorkSpaces Web 完整链路下面的示例综合了测试文件中的真实调用方式boto3 客户端、mock_aws装饰器演示从零创建到关联、再到清理的完整闭环import boto3 from moto import mock_aws mock_aws def test_workspaces_web_full_flow(): client boto3.client(workspaces-web, region_nameeu-west-1) # 1. 创建网络设置安全组/子网/VPC net_arn client.create_network_settings( securityGroupIds[sg-0123456789abcdef0], subnetIds[subnet-0123456789abcdef0, subnet-abcdef0123456789], vpcIdvpc-0123456789abcdef0, tags[{Key: Env, Value: test}], )[networkSettingsArn] # 2. 创建浏览器设置 browser_arn client.create_browser_settings( additionalEncryptionContext{Key1: Value1}, browserPolicyTestBrowserPolicy, clientTokenTestClient, customerManagedKeyabcd1234-5678-90ab-cdef-FAKEKEY, )[browserSettingsArn] # 3. 创建用户设置注意权限开关是字符串 user_arn client.create_user_settings( copyAllowedEnabled, pasteAllowedDisabled, printAllowedEnabled, uploadAllowedDisabled, downloadAllowedEnabled, )[userSettingsArn] # 4. 创建访问日志设置指向 Kinesis 流 logging_arn client.create_user_access_logging_settings( kinesisStreamArnarn:aws:kinesis:eu-west-1:123456789012:stream/TestStream )[userAccessLoggingSettingsArn] # 5. 创建门户 portal_arn, portal_endpoint ( client.create_portal( authenticationTypeStandard, displayNameTestDisplayName, instanceTypeTestInstanceType, maxConcurrentSessions5, tags[{Key: Env, Value: test}], )[portalArn], client.create_portal( authenticationTypeStandard, displayNameTestDisplayName, instanceTypeTestInstanceType, maxConcurrentSessions5, tags[{Key: Env, Value: test}], )[portalEndpoint], ) # 6. 建立双向关联 client.associate_network_settings(networkSettingsArnnet_arn, portalArnportal_arn) client.associate_browser_settings(browserSettingsArnbrowser_arn, portalArnportal_arn) client.associate_user_settings(userSettingsArnuser_arn, portalArnportal_arn) client.associate_user_access_logging_settings( userAccessLoggingSettingsArnlogging_arn, portalArnportal_arn ) # 7. 验证关联门户侧与设置侧都能看到对方 portal client.get_portal(portalArnportal_arn)[portal] assert portal[networkSettingsArn] net_arn assert portal[browserSettingsArn] browser_arn assert portal[userSettingsArn] user_arn assert portal[userAccessLoggingSettingsArn] logging_arn browser client.get_browser_settings(browserSettingsArnbrowser_arn)[browserSettings] assert browser[associatedPortalArns] [portal_arn] # 8. 标签追加、合并、删除 client.tag_resource(resourceArnportal_arn, tags[{Key: Team, Value: core}]) tags client.list_tags_for_resource(resourceArnportal_arn)[tags] assert {Key: Env, Value: test} in tags assert {Key: Team, Value: core} in tags client.untag_resource(resourceArnportal_arn, tagKeys[Env]) # 9. 清理删除资源 client.delete_portal(portalArnportal_arn) client.delete_network_settings(networkSettingsArnnet_arn) client.delete_browser_settings(browserSettingsArnbrowser_arn) client.delete_user_settings(userSettingsArnuser_arn) client.delete_user_access_logging_settings(userAccessLoggingSettingsArnlogging_arn) assert client.list_portals()[portals] []要点说明mock_aws会拦截 boto3 对该服务的全部请求无需真实凭证region_name决定后端实例与 ARN 中的区域段测试中可使用eu-west-1、ap-southeast-1等任意区域ARN 遵循arn:{partition}:workspaces-web:{region}:{account}:{resource}/{uuid}格式uuid.uuid4()保证每次创建的资源 ID 唯一权限开关传值必须是Enabled/Disabled字符串所有资源都以内存字典存储测试结束即释放无持久化副作用。响应层细节GET / DELETE 的路径解析响应层的单资源 GET 与 DELETE 走同一路径模板通过 HTTP 方法区分GET调用get_*其余方法DELETE调用delete_*见 moto/workspacesweb/responses.py。资源 ARN 从 URL 中按资源段提取network_settings_arn unquote(self.parsed_url.path.split(/networkSettings/)[-1])例如请求GET /networkSettings/arn%3Aaws%3Aworkspaces-web%3Aeu-west-1%3A123456789012%3Anetwork-settings%2F{uuid}时先对 URL 编码的 ARN 做unquote解码再以/networkSettings/为界取末段。DELETE 成功后返回空 JSON{}GET 成功则返回{networkSettings: {...}}之类的包裹结构。create_*请求的参数全部经self._get_param(xxx)从 JSON 请求体提取参数名与 AWS API 的 camelCase 字段一一对应。局限与后续演进方向当前实现仍有明显边界编写依赖这些能力的前置调研缺少 update 与 disassociateupdate_portal、update_browser_settings、update_network_settings、update_user_settings、update_user_access_logging_settings以及全部disassociate_*均未实现关联一旦建立便不可在内存中解除部分资源类型缺失data_protection_settings、ip_access_settings、session_logger、trust_store、identity_provider完全没有对应的模型与路由涉及这些资源的用例目前无法模拟门户字段为固定值browserType、rendererType、status、statusReason是写死的常量portalEndpoint使用虚构域名*.portal.aws不代表真实可用端点会话与元数据接口缺席expire_session、get_session、list_sessions、get_portal_service_provider_metadata等会话级 API 不在实现清单中。若需要这些能力可关注 Moto 后续版本对workspaces-web覆盖率的扩展当前版本建议把测试聚焦在本文已实现 API表格列出的 27 个操作上。小结Moto 的workspaces-web模块以四层架构URL → Response → Backend → Model完整模拟了 WorkSpaces Web 的五类核心资源与关联、标签能力并给出 27 个可直接调用的 API。借助 docs/docs/services/workspaces-web.rst 的覆盖清单开发者可以快速判断哪些操作可在本地测试中使用、哪些仍受限于实现边界。配合mock_aws装饰器与 tests/test_workspacesweb/test_workspacesweb.py 中的既有用例即可在 CI 中稳定验证门户创建、设置关联、标签管理与资源清理的完整业务逻辑。赞分享Mock测试【免费下载链接】motoA library that allows you to easily mock out tests based on AWS infrastructure.项目地址https://gitcode.com/gh_mirrors/mo/moto点击查看免费下载相关推荐Moto 中 Amazon WorkSpaces 服务的模拟实现指南已支持 API 全景与源码级剖析Moto 中 Amazon WorkSpaces 服务的模拟实现指南已支持 API 全景与源码级剖析 Amazon WorkSpaces 是 AWS 提供的托Mock测试Moto CleanRooms 服务模拟指南用 20 个已实现 API 在本地复现 AWS Clean RoomsMoto CleanRooms 服务模拟指南用 20 个已实现 API 在本地复现 AWS Clean Rooms 本篇技术指南聚焦 Moto 对 AWS CMock测试Moto AWS Support 服务模拟实战指南在本地测试中模拟 AWS 工单与 Trusted Advisor 检查Moto AWS Support 服务模拟实战指南在本地测试中模拟 AWS 工单与 Trusted Advisor 检查 本篇技术指南围绕 Moto 项目中Mock测试上一篇MTKClient从零到上手一条命令备份与刷写联发科设备固件全攻略下一篇C盘爆红不用慌三步用WindowsCleaner完成Windows系统清理与加速创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考