☰
AWS SDK for Java V2 测试生成实战:基于 JUnit 5 与 Mockito 的单元、集成与场景测试完整指南
2026/10/7 16:14:16 网站建设 项目流程
  • 示例工程
  • 教程
  • 后端

【免费下载链接】aws-doc-sdk-examples

Welcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below.

项目地址:https://gitcode.com/gh_mirrors/aw/aws-doc-sdk-examples
点击查看免费下载

本篇技术指南以 AWS 文档代码示例仓库(aws-doc-sdk-examples)中 Java V2 示例的测试生成规范为主线,系统讲解如何为 AWS SDK for Java V2 示例代码编写单元测试(Unit Tests)、集成测试(Integration Tests)与场景测试(Scenario Tests)。文章覆盖从测试前知识库检索、Maven 依赖与 Surefire 分组配置,到三类测试的标准代码骨架、完整 AWS 数据结构使用、测试执行命令与常见失败规避的完整链路。阅读完本文,你将能够在javav2/example_code/{service}目录下独立生成符合仓库规范、可一键运行并可被持续集成复用的 Java 测试套件。

一、测试生成的第一原则:先检索知识库,再动手写代码

在生成任何 Java 测试代码之前,必须完成知识库(Knowledge Base)咨询流程。这是本仓库 Java 测试生成的强制前置步骤(MANDATORY),跳过该步骤将导致生成的代码结构与仓库既有规范不一致(文档原文标注为 "CRITICAL - Must be completed BEFORE any code generation")。

整个流程分为四个固定步骤:

  1. 列出可用知识库:调用ListKnowledgeBases(),确认当前环境可用的知识库列表;
  2. 查询编码规范(必选):调用QueryKnowledgeBases("coding-standards-KB", "Java-code-example-standards"),获取仓库约定的 Java 代码示例标准;
  3. 查询实现模式(必选):调用QueryKnowledgeBases("Java-premium-KB", "Java implementation patterns testing"),获取 Java 实现模式的测试写法;
  4. 调研目标 AWS 服务(必选):针对待测试的服务,使用search_documentation("What is [AWS Service] and what are its key API operations?")检索服务定义与关键 API 操作,再通过read_documentation("https://docs.aws.amazon.com/[service]/latest/[relevant-page]")读取对应官方文档页面,明确该服务涉及的请求/响应模型与异常类型。

需要特别强调的是,步骤 2 至 4 均为必选项(REQUIRED)。AWS 服务的异常类型(如{Service}Exception及BadRequestException、ResourceNotFoundException等细分错误码)只有通过官方文档确认后,才能在测试中准确地模拟与断言。

二、测试目标、技术选型与文件结构

2.1 测试目标

生成的测试套件需要覆盖三类测试:

  • 单元测试(Unit Tests):用 Mockito Mock AWS SDK Client,隔离测试单个 action 方法,覆盖成功与异常分支,执行快、不发起真实 AWS 调用;
  • 集成测试(Integration Tests):使用真实 AWS Client 与真实服务交互,端到端验证完整工作流,需要 AWS 凭据与权限,必须包含资源清理逻辑;
  • 场景测试(Scenario Tests):以模拟用户输入驱动{Service}Scenario.main()运行完整业务场景,验证控制台输出与用户交互路径,通常归类为集成测试类别(需要真实 AWS)。

2.2 技术栈要求

  • JUnit 5:所有测试统一使用 JUnit Jupiter(JUnit 5 注解体系);
  • Mockito:单元测试中使用 Mockito 模拟 AWS SDK Client;
  • 完整数据:测试中必须使用完整的 AWS 数据结构(见第四节);
  • 测试分组:使用 JUnit Tag 对测试进行分类;
  • 错误覆盖:规格(specification)中列出的所有错误条件都必须有对应测试。

2.3 标准文件结构

测试文件统一放置于服务模块的src/test/java目录,按职责拆分为三个文件:

javav2/example_code/{service}/src/test/java/ ├── {Service}ActionsTest.java # 单元测试(actions) ├── {Service}IntegrationTest.java # 集成测试 └── {Service}ScenarioTest.java # 场景测试

这一结构与仓库实际布局一致。例如 EC2 集成测试 位于javav2/example_code/ec2/src/test/java/,SES 场景测试 位于javav2/example_code/ses/src/test/java/com/example/sesv2/,SQS 单元测试 位于javav2/example_code/sqs/src/test/java/com/example/sqs/。命名约定上,仓库历史测试多采用{Service}Test.java风格(如 EC2Test.java、CloudWatchTest.java),新生成的测试可按照上述{Service}ActionsTest / {Service}IntegrationTest / {Service}ScenarioTest三分结构组织。

三、Maven 测试配置:依赖、Surefire 分组与 Profile

3.1 标准依赖声明

测试依赖的核心是 JUnit Jupiter 与 Mockito 全家桶:

<dependencies> <!-- AWS SDK --> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>{service}</artifactId> <version>${aws.java.sdk.version}</version> </dependency> <!-- Test Dependencies --> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>5.10.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>5.5.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-junit-jupiter</artifactId> <version>5.5.0</version> <scope>test</scope> </dependency> </dependencies>

从仓库的实际pom.xml可以看到,该版本基线是可选的,真实项目往往通过 BOM 统一管理 AWS SDK 版本。例如 EC2 的 pom.xml 使用dependencyManagement导入software.amazon.awssdk:bom:2.35.10,测试依赖使用org.junit.jupiter:junit-jupiter:5.11.4(scope 为 test),编译目标为 Java 21;SES 的 pom.xml 还额外引入了org.hamcrest:hamcrest-all与org.assertj:assertj-core作为断言库。此外,多数服务模块还依赖secretsmanager、gson等用于集成测试的配置读取。因此在实际开发中建议优先参考仓库内同服务的既有pom.xml,保持版本管理方式一致。

3.2 Surefire 按测试分组执行

利用@Tag("integration")将集成/场景测试标记出来,再通过 Surefire 的groups参数控制默认执行范围——默认只跑非集成测试,集成测试由独立 Profile 显式触发:

<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.1.2</version> <configuration> <groups>!integration</groups> </configuration> </plugin> </plugins> </build> <profiles> <profile> <id>integration</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <groups>integration</groups> </configuration> </plugin> </plugins> </build> </profile> </profiles>

仓库中的 Surefire 版本略新(如 EC2 pom.xml 与 SES pom.xml 均使用3.5.2),groups/excludedGroups的机制一致。仓库还提供了批量测试入口脚本 javav2/run_tests.sh,它会递归扫描example_code下所有包含pom.xml的目录并执行mvn test -Dgroups=weathertop -DexcludedGroups=quarantine,可见分组 Tag 的隔离能力在仓库级自动化中被直接依赖。

四、单元测试模式(Unit Test Pattern)

单元测试的核心是用 Mockito 构造{Service}Client的 Mock,把被测 action 方法从真实 AWS 网络调用中隔离出来。标准骨架如下:

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package com.example.{service}; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import software.amazon.awssdk.services.{service}.{Service}Client; import software.amazon.awssdk.services.{service}.model.*; import software.amazon.awssdk.core.exception.SdkException; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) class {Service}ActionsTest { @Mock private {Service}Client {service}Client; private {Service}Actions {service}Actions; @BeforeEach void setUp() { {service}Actions = new {Service}Actions(); } @Test void test{ActionName}_Success() { // Arrange String testParam = "test-value"; {ActionName}Response expectedResponse = {ActionName}Response.builder() .{responseField}("response-value") .build(); when({service}Client.{actionName}(any({ActionName}Request.class))) .thenReturn(expectedResponse); // Act {ActionName}Response result = {service}Actions.{actionName}({service}Client, testParam); // Assert assertNotNull(result); assertEquals("response-value", result.{responseField}()); verify({service}Client).{actionName}(any({ActionName}Request.class)); } @ParameterizedTest @ValueSource(strings = {"BadRequestException", "InternalServerErrorException", "ResourceNotFoundException"}) void test{ActionName}_ServiceException(String errorCode) { // Arrange String testParam = "test-value"; {Service}Exception serviceException = ({Service}Exception) {Service}Exception.builder() .awsErrorDetails(AwsErrorDetails.builder() .errorCode(errorCode) .errorMessage("Test error message") .build()) .build(); when({service}Client.{actionName}(any({ActionName}Request.class))) .thenThrow(serviceException); // Act & Assert {Service}Exception exception = assertThrows({Service}Exception.class, () -> {service}Actions.{actionName}({service}Client, testParam)); assertEquals(errorCode, exception.awsErrorDetails().errorCode()); verify({service}Client).{actionName}(any({ActionName}Request.class)); } @Test void test{ActionName}_SdkException() { // Arrange String testParam = "test-value"; SdkException sdkException = SdkException.builder() .message("SDK error occurred") .build(); when({service}Client.{actionName}(any({ActionName}Request.class))) .thenThrow(sdkException); // Act & Assert SdkException exception = assertThrows(SdkException.class, () -> {service}Actions.{actionName}({service}Client, testParam)); assertEquals("SDK error occurred", exception.getMessage()); verify({service}Client).{actionName}(any({ActionName}Request.class)); } }

该模式包含三个关键要点:

  • Arrange / Act / Assert 三段式:先用when(...).thenReturn(...)编排 Mock 行为,再调用被测方法,最后用assertNotNull/assertEquals断言返回值,并用verify(...)确认 Mock 确实收到了请求;
  • 异常分支全覆盖:既测试{Service}Exception(AWS 服务侧错误,通过awsErrorDetails().errorCode()校验具体错误码),也测试底层SdkException(SDK 层通用错误),保证两条错误路径都被覆盖;
  • 参数化测试:用@ParameterizedTest+@ValueSource一次性注入BadRequestException、InternalServerErrorException、ResourceNotFoundException等多个错误码,避免为每个错误码重复编写测试方法。

仓库中有大量此类写法的实证。例如 SQS 单元测试 SSEncryptionExampleUnitTest.java 使用mock(SqsClient.class)创建 Mock、when(mockSqsClient.getQueueUrl(...)).thenReturn(...)编排响应、verify(mockSqsClient).getQueueUrl(...)断言调用,并通过MockedStatic模拟SqsClient::create静态工厂方法;SES 的 NewsletterWorkflowTest.java 则使用@Mock private SesV2Client sesClient配合MockitoAnnotations.openMocks(this)初始化 Mock。两种 Mockito 初始化方式(JUnit 5 扩展与手动 openMocks)在仓库中都存在,新代码推荐使用文档所示@ExtendWith(MockitoExtension.class)的声明式写法。

五、完整 AWS 数据结构(Complete AWS Data Structures)

这是本规范中反复强调的CRITICAL要求:Mock 返回的 AWS 响应对象必须使用完整字段,而不是只填充单个标识符的最小对象。最小化的数据结构会导致校验失败、下游逻辑 NPE 或断言失真。

// ❌ WRONG - Minimal data that fails validation List<{Resource}> resources = List.of( {Resource}.builder() .{resourceId}("resource-1") .build() ); // ✅ CORRECT - Complete AWS data structure List<{Resource}> resources = List.of( {Resource}.builder() .{resourceId}("resource-1") .{resourceName}("test-resource") .{resourceArn}("arn:aws:service:region:account:resource/resource-1") .{resourceStatus}({ResourceStatus}.ACTIVE) .{createdAt}(Instant.now()) .{updatedAt}(Instant.now()) .{tags}(Map.of("Environment", "Test")) .build() );

正确写法应在 Builder 上补齐资源标识符(resourceId)、名称(resourceName)、ARN、状态枚举(resourceStatus)、创建/更新时间戳(createdAt / updatedAt)以及标签(tags)等完整字段。对 ARN 这类字段应构造符合 AWS 格式的真实值(arn:aws:{service}:{region}:{account}:resource/{resourceId}),对枚举字段应使用语义正确的值(如{ResourceStatus}.ACTIVE)。这样 Mock 出来的对象与真实服务返回对象在结构上等价,测试断言才有意义。

六、集成测试模式(Integration Test Pattern)

集成测试使用真实 AWS Client 连接真实服务,通过@Tag("integration")与单元测试隔离,默认 Maven 构建不会执行它们。

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package com.example.{service}; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.AfterAll; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.{service}.{Service}Client; import software.amazon.awssdk.services.{service}.model.*; import static org.junit.jupiter.api.Assertions.*; @Tag("integration") class {Service}IntegrationTest { private static {Service}Client {service}Client; private static {Service}Actions {service}Actions; private static String testResourceId; @BeforeAll static void setUp() { {service}Client = {Service}Client.builder() .region(Region.US_EAST_1) .build(); {service}Actions = new {Service}Actions(); } @AfterAll static void tearDown() { // Clean up test resources if (testResourceId != null) { try { {service}Actions.deleteResource({service}Client, testResourceId); } catch (Exception e) { // Ignore cleanup errors } } if ({service}Client != null) { {service}Client.close(); } } @Test void testResourceLifecycle() { try { // Create resource testResourceId = {service}Actions.createResource({service}Client); assertNotNull(testResourceId); // Get resource {Resource} resource = {service}Actions.getResource({service}Client, testResourceId); assertNotNull(resource); assertEquals(testResourceId, resource.{resourceId}()); // List resources (should include our test resource) List<{Resource}> resources = {service}Actions.listResources({service}Client); assertTrue(resources.stream() .anyMatch(r -> testResourceId.equals(r.{resourceId}()))); } catch (Exception e) { fail("Integration test failed: " + e.getMessage()); } } @Test void testServiceConnectivity() { // Test basic service connectivity assertDoesNotThrow(() -> { List<{Resource}> resources = {service}Actions.listResources({service}Client); assertNotNull(resources); }); } }

该模式的关键设计:

  • 生命周期测试:在一个测试内完成资源 create → get → list 的完整生命周期验证,并断言创建出的资源 ID 能在 list 结果中被找到;
  • 连接性测试:testServiceConnectivity用assertDoesNotThrow验证凭据配置与网络连通性本身没有问题;
  • 清理与关闭:@AfterAll中删除测试资源并调用{service}Client.close()释放连接;清理失败时捕获异常忽略,避免清理问题掩盖测试主结果;
  • Region 显式指定:Client 构建时通过region(Region.US_EAST_1)显式指定区域,这是检查清单中的强制项。

仓库的集成测试实践在细节上更丰富。以 EC2Test.java 为例,它通过@TestInstance(TestInstance.Lifecycle.PER_METHOD)+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)+@Order(n)控制测试执行顺序(依赖先创建资源、后清理),测试所需参数(keyName、VPC ID、安全组描述等)在@BeforeAll中从 AWS Secrets Manager 读取(仓库多数服务集成测试采用此配置注入方式,避免把敏感值硬编码进代码),并在测试方法上标注@Tag("IntegrationTest")。可以看到仓库 Tag 命名有历史差异(IntegrationTest与integration并存),新代码遵循本文档统一使用@Tag("integration")。

七、场景测试模式(Scenario Test Pattern)

场景测试驱动完整的{Service}Scenario.main()入口,通过重定向System.in模拟用户键盘输入、重定向System.out捕获控制台输出,验证端到端场景的输出内容与多路径分支。

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package com.example.{service}; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.AfterEach; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.{service}.{Service}Client; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.PrintStream; import static org.junit.jupiter.api.Assertions.*; @Tag("integration") class {Service}ScenarioTest { private {Service}Client {service}Client; private ByteArrayOutputStream outputStream; private PrintStream originalOut; @BeforeEach void setUp() { {service}Client = {Service}Client.builder() .region(Region.US_EAST_1) .build(); // Capture System.out for testing outputStream = new ByteArrayOutputStream(); originalOut = System.out; System.setOut(new PrintStream(outputStream)); } @AfterEach void tearDown() { System.setOut(originalOut); if ({service}Client != null) { {service}Client.close(); } } @Test void testScenarioWithMockedInput() { // Mock user inputs for automated testing String simulatedInput = "n\nn\ny\n"; // No existing resource, no details, yes cleanup System.setIn(new ByteArrayInputStream(simulatedInput.getBytes())); // Run scenario assertDoesNotThrow(() -> { {Service}Scenario.main(new String[]{"us-east-1"}); }); // Verify output contains expected messages String output = outputStream.toString(); assertTrue(output.contains("Welcome to the {AWS Service} basics scenario!")); assertTrue(output.contains("Setting up {AWS Service}")); } @Test void testScenarioWithExistingResources() { // Create a test resource first String testResourceId = null; try { {Service}Actions actions = new {Service}Actions(); testResourceId = actions.createResource({service}Client); // Mock user inputs to use existing resource String simulatedInput = "y\nn\ny\n"; // Yes existing, no details, yes cleanup System.setIn(new ByteArrayInputStream(simulatedInput.getBytes())); // Run scenario assertDoesNotThrow(() -> { {Service}Scenario.main(new String[]{"us-east-1"}); }); String output = outputStream.toString(); assertTrue(output.contains("Found")); assertTrue(output.contains("existing resource")); } finally { // Clean up test resource if (testResourceId != null) { try { new {Service}Actions().deleteResource({service}Client, testResourceId); } catch (Exception e) { // Ignore cleanup errors } } } } }

要点说明:

  • 输入模拟:System.setIn(new ByteArrayInputStream(simulatedInput.getBytes()))以换行符分隔的字符串序列模拟用户在控制台的依次回车输入(如"n\nn\ny\n"表示"无现有资源、不查看详情、执行清理"),配合@AfterEach中恢复原始流避免污染其他测试;
  • 输出捕获与断言:System.setOut重定向到ByteArrayOutputStream,运行场景后用output.contains("...")断言关键提示信息(欢迎语、初始化信息)确实打印;
  • 多路径覆盖:testScenarioWithExistingResources先真实创建一个资源,再用"y\nn\ny\n"模拟用户选择"使用现有资源"的路径,验证 "Found existing resource" 分支,从而覆盖新增与复用两条用户路径;
  • 资源清理:使用try/finally结构,即使断言失败也确保测试资源被删除,避免遗留 AWS 资源产生费用。

仓库中的 SES NewsletterWorkflowTest.java 是场景测试的成熟实例:它在@Before中通过System.setOut/System.setErr捕获输出,通过注入的NewsletterScannerMock 模拟用户输入(如when(scanner.nextLine()).thenReturn("test@example.com")),并在断言中使用 Hamcrest 的assertThat(outContent.toString(), containsString("Email identity created: test@example.com"))验证控制台输出。

八、测试执行命令

进入服务模块目录后,按需选择以下 Maven 命令:

# 只跑单元测试(默认 Surefire 配置已排除 integration 分组) cd javav2/example_code/{service} mvn test -Dgroups="!integration" # 只跑集成/场景测试(需要有效 AWS 凭据) cd javav2/example_code/{service} mvn test -Dgroups="integration" # 跑全部测试 cd javav2/example_code/{service} mvn test # 只跑某个测试类 mvn test -Dtest="{Service}ActionsTest"

命令语义与 Surefire 的groups配置一一对应:-Dgroups="!integration"排除集成测试(默认构建行为),-Dgroups="integration"单独执行标记为@Tag("integration")的测试。仓库层面的批量执行可直接运行 javav2/run_tests.sh,该脚本递归遍历example_code下所有含pom.xml的模块执行mvn test,并在仓库级实现了按 Tag 的隔离(-Dgroups=weathertop -DexcludedGroups=quarantine)。

九、测试要求检查清单(Test Requirements Checklist)

生成测试前逐项核对:

  • ✅JUnit 5 注解:@Test、@BeforeEach、@AfterEach正确使用
  • ✅Mockito 用于单元测试:@Mock+@ExtendWith(MockitoExtension.class)
  • ✅完整 AWS 数据结构:所有测试均使用完整字段的响应对象
  • ✅正确的测试 Tag:集成/场景测试标记@Tag("integration")
  • ✅错误条件覆盖:规格中声明的错误条件全部有对应测试
  • ✅集成测试清理:使用try/finally块确保资源释放
  • ✅Region 显式指定:测试 Client 构建时传入Region.US_EAST_1
  • ✅资源生命周期测试:覆盖 create、read、delete
  • ✅参数化测试:对多个错误条件使用@ParameterizedTest

十、测试分类速览

测试类别核心特征是否需要真实 AWS
单元测试Mockito Mock AWS Client;方法级隔离;覆盖成功与错误分支;执行快否
集成测试真实 Client 端到端工作流;需要凭据与权限;包含清理逻辑防资源泄漏是
场景测试模拟用户输入;验证控制台输出与交互;覆盖多用户路径;归类为集成类别是

十一、常见测试失败点规避(Common Test Failures to Avoid)

文档明确列出以下高发错误,生成与审查测试时逐条对照:

  • ❌ 在 Mock 中使用不完整的 AWS 数据结构(违反第五节 CRITICAL 要求);
  • ❌ 集成测试缺失@Tag("integration"),导致默认mvn test误执行真实 AWS 调用或集成测试无法被分组筛选;
  • ❌ 集成测试未做资源清理,遗留资源产生 AWS 费用;
  • ❌ 测试 Client 忘记显式设置 AWS Region;
  • ❌ 未覆盖规格中声明的全部错误条件;
  • ❌ 场景测试未模拟用户输入(直接运行会阻塞在Scanner等待输入);
  • ❌ 缺少 Maven 测试配置(JUnit/Mockito 依赖或 Surefire 分组缺失);
  • ❌ JUnit 5 注解使用不规范(如混用 JUnit 4 的org.junit.Test,导致与@BeforeEach等 JUnit 5 注解冲突)。

十二、与仓库生态的衔接

本测试规范服务于仓库内全部 Java V2 AWS 服务示例,落地形态分散在 javav2/example_code 下各服务模块的src/test/java目录。深入学习时建议:

  • 阅读 javav2/README.md 了解 Java V2 示例的整体组织与运行环境要求;
  • 对照本文档模式,重点研读 EC2Test.java(集成测试 + Secrets Manager 参数注入 + 顺序控制)、NewsletterWorkflowTest.java(场景测试 + 输出捕获 + Scanner Mock)、SSEncryptionExampleUnitTest.java(纯单元测试 + 静态方法 Mock);
  • 以 ec2/pom.xml 与 ses/pom.xml 为模板核对 Maven 依赖、BOM 版本管理、Surefire 与编译插件配置;
  • 批量测试流水线参考 javav2/run_tests.sh 的分组隔离与递归执行策略。

以上模式与配置均以当前仓库的实际源码为准,生成测试时请结合目标服务模块既有代码结构、SDK 版本与异常类型进行适配。

  • 示例工程
  • 教程
  • 后端

【免费下载链接】aws-doc-sdk-examples

Welcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below.

项目地址:https://gitcode.com/gh_mirrors/aw/aws-doc-sdk-examples
点击查看免费下载

相关推荐

上一篇:lsp-status.nvim 与 nvim-lsp/lspconfig 无缝集成教程:3 步点亮你的状态栏
下一篇:从零开始掌握yuzu模拟器:5步解决常见问题,畅玩Switch游戏

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询