CtrlK
BlogDocsLog inGet started
Tessl Logo

giuseppe-trisciuoglio/developer-kit

Comprehensive developer toolkit providing reusable skills for Java/Spring Boot, TypeScript/NestJS/React/Next.js, Python, PHP, AWS CloudFormation, AI/RAG, DevOps, and more.

89

Quality

89%

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Risky

Do not use without reviewing

Overview
Quality
Evals
Security
Files

testing.mdplugins/developer-kit-java/skills/aws-sdk-java-v2-lambda/references/

Testing Lambda Services

Unit Testing with Mocks

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import software.amazon.awssdk.services.lambda.LambdaClient;
import software.amazon.awssdk.services.lambda.model.InvokeResponse;
import software.amazon.awssdk.core.SdkBytes;

import static org.mockito.Mockito.*;
import static org.assertj.core.api.Assertions.*;

@ExtendWith(MockitoExtension.class)
class LambdaInvokerServiceTest {

    @Mock
    private LambdaClient lambdaClient;

    @Mock
    private ObjectMapper objectMapper;

    @InjectMocks
    private LambdaInvokerService service;

    @Test
    void shouldInvokeLambdaSuccessfully() throws Exception {
        // Arrange
        String functionName = "test-function";
        OrderRequest request = new OrderRequest("123", List.of());

        String jsonPayload = "{\"orderId\":\"123\",\"items\":[]}";
        String jsonResponse = "{\"status\":\"SUCCESS\"}";

        when(objectMapper.writeValueAsString(request)).thenReturn(jsonPayload);
        when(objectMapper.readValue(jsonResponse, OrderResponse.class))
            .thenReturn(new OrderResponse("SUCCESS"));

        InvokeResponse invokeResponse = InvokeResponse.builder()
            .statusCode(200)
            .payload(SdkBytes.fromUtf8String(jsonResponse))
            .build();

        when(lambdaClient.invoke(any(InvokeRequest.class))).thenReturn(invokeResponse);

        // Act
        OrderResponse response = service.invoke(functionName, request, OrderResponse.class);

        // Assert
        assertThat(response.getStatus()).isEqualTo("SUCCESS");

        InvokeRequest expectedRequest = InvokeRequest.builder()
            .functionName(functionName)
            .payload(SdkBytes.fromUtf8String(jsonPayload))
            .build();

        verify(lambdaClient).invoke(expectedRequest);
    }

    @Test
    void shouldHandleLambdaFunctionError() throws Exception {
        // Arrange
        String functionName = "test-function";
        OrderRequest request = new OrderRequest("123", List.of());
        String jsonPayload = "{\"orderId\":\"123\",\"items\":[]}";
        String errorResponse = "{\"error\":\"Invalid input\"}";

        when(objectMapper.writeValueAsString(request)).thenReturn(jsonPayload);

        InvokeResponse invokeResponse = InvokeResponse.builder()
            .statusCode(200)
            .functionError("Unhandled")
            .payload(SdkBytes.fromUtf8String(errorResponse))
            .build();

        when(lambdaClient.invoke(any(InvokeRequest.class))).thenReturn(invokeResponse);

        // Act & Assert
        assertThatThrownBy(() -> service.invoke(functionName, request, OrderResponse.class))
            .isInstanceOf(LambdaInvocationException.class)
            .hasMessageContaining("Lambda function error");
    }

    @Test
    void shouldHandleServiceException() {
        // Arrange
        String functionName = "test-function";
        OrderRequest request = new OrderRequest("123", List.of());

        when(lambdaClient.invoke(any(InvokeRequest.class)))
            .thenThrow(new LambdaException("Service unavailable"));

        // Act & Assert
        assertThatThrownBy(() -> service.invoke(functionName, request, OrderResponse.class))
            .isInstanceOf(RuntimeException.class)
            .hasMessageContaining("Failed to invoke Lambda function");
    }
}

Integration Testing

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import static org.assertj.core.api.Assertions.*;

@SpringBootTest
@ActiveProfiles("test")
class LambdaInvokerServiceIntegrationTest {

    @Autowired
    private LambdaInvokerService lambdaInvoker;

    @Test
    void shouldInvokeRealLambdaFunction() {
        // Arrange
        String functionName = "test-function";
        TestRequest request = new TestRequest("test-data");

        // Act
        TestResponse response = lambdaInvoker.invoke(functionName, request, TestResponse.class);

        // Assert
        assertThat(response).isNotNull();
        assertThat(response.getStatus()).isEqualTo("SUCCESS");
    }
}

Testing with LocalStack

import org.testcontainers.containers.localstack.LocalStackContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.lambda.LambdaClient;

@SpringBootTest
@Testcontainers
class LambdaLocalStackTest {

    @Container
    static LocalStackContainer localstack = new LocalStackContainer(
        DockerImageName.parse("localstack/localstack:latest"))
        .withServices(LocalStackContainer.Service.LAMBDA);

    @DynamicPropertySource
    static void configureProperties(DynamicPropertyRegistry registry) {
        registry.add("aws.endpoint", localstack::getEndpoint);
        registry.add("aws.region", () -> "us-east-1");
    }

    @Bean
    public LambdaClient lambdaClient() {
        return LambdaClient.builder()
            .endpointOverride(URI.create(localstack.getEndpoint()))
            .region(Region.US_EAST_1)
            .credentialsProvider(StaticCredentialsProvider.create(
                AwsBasicCredentials.create("test", "test")))
            .build();
    }
}

Testing Async Invocations

@ExtendWith(MockitoExtension.class)
class AsyncLambdaServiceTest {

    @Mock
    private LambdaAsyncClient asyncClient;

    @InjectMocks
    private AsyncLambdaService asyncService;

    @Test
    void shouldInvokeLambdaAsync() throws Exception {
        // Arrange
        String functionName = "test-function";
        String payload = "{\"test\":\"data\"}";

        CompletableFuture<InvokeResponse> future = CompletableFuture.completedFuture(
            InvokeResponse.builder()
                .statusCode(202)
                .payload(SdkBytes.fromUtf8String("{\"status\":\"accepted\"}"))
                .build()
        );

        when(asyncClient.invoke(any(InvokeRequest.class))).thenReturn(future);

        // Act
        CompletableFuture<String> result = asyncService.invokeAsync(functionName, payload);

        // Assert
        assertThat(result.get()).contains("accepted");
    }
}

Testing Error Scenarios

@Test
void shouldHandleTimeout() {
    // Arrange
    when(lambdaClient.invoke(any(InvokeRequest.class)))
        .thenAnswer(invocation -> {
            Thread.sleep(5000); // Simulate timeout
            return InvokeResponse.builder().build();
        });

    // Act & Assert
    assertThatThrownBy(() -> service.invoke("function", request, Response.class))
        .isInstanceOf(RuntimeException.class);
}

@Test
void shouldRetryOnTransientFailure() {
    // Arrange
    when(lambdaClient.invoke(any(InvokeRequest.class)))
        .thenThrow(new LambdaException("Service unavailable"))
        .thenReturn(InvokeResponse.builder()
            .statusCode(200)
            .payload(SdkBytes.fromUtf8String("{\"status\":\"ok\"}"))
            .build());

    // Act
    Response response = service.invokeWithRetry("function", request, Response.class, 3);

    // Assert
    assertThat(response.getStatus()).isEqualTo("ok");
    verify(lambdaClient, times(2)).invoke(any(InvokeRequest.class));
}

Test Fixtures

class LambdaTestFixture {
    public static InvokeResponse successResponse(String payload) {
        return InvokeResponse.builder()
            .statusCode(200)
            .payload(SdkBytes.fromUtf8String(payload))
            .build();
    }

    public static InvokeResponse errorResponse(String error) {
        return InvokeResponse.builder()
            .statusCode(200)
            .functionError("Handled")
            .payload(SdkBytes.fromUtf8String("{\"error\":\"" + error + "\"}"))
            .build();
    }

    public static InvokeRequest invokeRequest(String functionName, String payload) {
        return InvokeRequest.builder()
            .functionName(functionName)
            .payload(SdkBytes.fromUtf8String(payload))
            .build();
    }
}

plugins

developer-kit-java

skills

README.md

CHANGELOG.md

context7.json

CONTRIBUTING.md

README_CN.md

README_ES.md

README_IT.md

README.md

tessl.json

tile.json