Wraps Amazon.Lambda.TestTool (the canonical .NET Lambda local-testing toolkit from github.com/aws/aws-lambda-dotnet) for invoking Lambda handlers from xUnit / NUnit tests with simulated AWS Lambda contexts (ILambdaContext, ILambdaSerializer). Covers handler-direct invocation, mock context fixtures, the dotnet-lambda CLI, and integration with the .NET LambdaSerializer for JSON. Use when testing AWS Lambda functions written in C#/.NET.
75
94%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Amazon.Lambda.TestTool is AWS's canonical .NET package for
testing Lambda functions. Per
github.com/aws/aws-lambda-dotnet,
it provides a Mock Lambda Test Tool (Windows / Mac / Linux UI to
manually invoke Lambdas) plus library-level fakes for
ILambdaContext.
For automated tests, the pattern is handler-direct invocation with a mock context.
dotnet lambda invoke per test.dotnet add package Amazon.Lambda.Core
dotnet add package Amazon.Lambda.Serialization.SystemTextJson
dotnet add package Amazon.Lambda.TestUtilities # NUnit-friendly mocks
dotnet add package Microsoft.NET.Test.Sdk
dotnet add package xunitusing Amazon.Lambda.Core;
using Amazon.Lambda.Serialization.SystemTextJson;
[assembly: LambdaSerializer(typeof(DefaultLambdaJsonSerializer))]
public class Functions
{
public string Handler(string input, ILambdaContext context)
{
context.Logger.LogLine($"Got input: {input}");
return input.ToUpper();
}
}Per aws-lambda-dotnet Amazon.Lambda.TestUtilities:
using Amazon.Lambda.TestUtilities;
using Xunit;
public class FunctionsTests
{
[Fact]
public void Handler_Uppercases()
{
var functions = new Functions();
var context = new TestLambdaContext
{
FunctionName = "test-fn",
RemainingTime = TimeSpan.FromSeconds(30),
// Logger is auto-set to TestLambdaLogger
};
var result = functions.Handler("hello", context);
Assert.Equal("HELLO", result);
}
[Fact]
public void Handler_LogsInput()
{
var functions = new Functions();
var context = new TestLambdaContext();
functions.Handler("hi", context);
var logger = (TestLambdaLogger)context.Logger;
Assert.Contains("Got input: hi", logger.Buffer.ToString());
}
}Per lambda-timeout-budget-reference,
handlers that check Context.RemainingTime:
[Fact]
public void Handler_EarlyReturnsWhenTimeLow()
{
var functions = new Functions();
var context = new TestLambdaContext
{
RemainingTime = TimeSpan.FromSeconds(3) // Below 5s threshold
};
var result = functions.Handler("work-that-takes-time", context);
Assert.Contains("partial", result);
}[Fact]
public void Handler_ParsesApiGatewayEvent()
{
var json = File.ReadAllText("Events/apigw-request.json");
var serializer = new DefaultLambdaJsonSerializer();
var request = serializer.Deserialize<APIGatewayProxyRequest>(json);
var functions = new Functions();
var response = functions.HandleApi(request, new TestLambdaContext());
Assert.Equal(200, response.StatusCode);
}Per github.com/aws/aws-extensions-for-dotnet-cli:
dotnet tool install -g Amazon.Lambda.Tools
dotnet lambda invoke-function MyFunction --payload '"hello"'For local-only testing, prefer the handler-direct pattern above.
dotnet testFor watch-mode:
dotnet watch testjobs:
dotnet-lambda-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-dotnet@v4
with: { dotnet-version: '8.0.x' }
- run: dotnet restore
- run: dotnet test --no-build --verbosity normal| Anti-pattern | Why it fails | Fix |
|---|---|---|
Spawn dotnet lambda invoke per test | Network calls; slow; rate-limited | Handler-direct invocation |
Skip TestLambdaContext | Real ILambdaContext is required; null fails | Always pass a context |
RemainingTime = TimeSpan.MaxValue | Doesn't exercise timeout logic | Set realistic remaining time |
| Hand-rolled APIGatewayProxyRequest | Schema drift | Generate via sam local generate-event or commit fixture |
| Test using prod IAM | Permissions surprise in CI | Use mock service clients |
| No assertion on logger output | Logger bugs slip through | Inspect TestLambdaLogger.Buffer |
| Serializer not registered | LambdaSerializer attribute missing → runtime fails | Add assembly attribute |
| Mocking the Logger | Loses TestLambdaLogger's buffer-replay capability | Use TestLambdaContext's default logger |
next / response polling) isn't invoked;
bugs in handler-vs-runtime contract slip through.cold-start-budget-reference.
In-process tests are warm; AOT cold-start savings invisible.cold-start-budget-reference,
lambda-timeout-budget-reference.aws-sam-local-testing
(Node/Python/Java equivalent).