Skip to content

Commit 1d13044

Browse files
committed
📚
1 parent b8bfe9d commit 1d13044

File tree

5 files changed

+143
-353
lines changed

5 files changed

+143
-353
lines changed

CommandQuery.AWSLambda.md

Lines changed: 40 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,12 @@ namespace CommandQuery.Sample.AWSLambda;
4949

5050
public class Command(ICommandFunction commandFunction)
5151
{
52-
[LambdaFunction]
52+
[LambdaFunction(Policies = "AWSLambdaBasicExecutionRole", MemorySize = 256, Timeout = 30)]
5353
[RestApi(LambdaHttpMethod.Post, "/command/{commandName}")]
54-
public async Task<APIGatewayProxyResponse> Handle(APIGatewayProxyRequest request, ILambdaContext context, string commandName) =>
54+
public async Task<APIGatewayProxyResponse> Post(
55+
APIGatewayProxyRequest request,
56+
ILambdaContext context,
57+
string commandName) =>
5558
await commandFunction.HandleAsync(commandName, request, context.Logger);
5659
}
5760
```
@@ -79,14 +82,20 @@ namespace CommandQuery.Sample.AWSLambda
7982
{
8083
public class Query(IQueryFunction queryFunction)
8184
{
82-
[LambdaFunction]
85+
[LambdaFunction(Policies = "AWSLambdaBasicExecutionRole", MemorySize = 256, Timeout = 30)]
8386
[RestApi(LambdaHttpMethod.Get, "/query/{queryName}")]
84-
public async Task<APIGatewayProxyResponse> Get(APIGatewayProxyRequest request, ILambdaContext context, string queryName) =>
87+
public async Task<APIGatewayProxyResponse> Get(
88+
APIGatewayProxyRequest request,
89+
ILambdaContext context,
90+
string queryName) =>
8591
await queryFunction.HandleAsync(queryName, request, context.Logger);
8692

87-
[LambdaFunction]
93+
[LambdaFunction(Policies = "AWSLambdaBasicExecutionRole", MemorySize = 256, Timeout = 30)]
8894
[RestApi(LambdaHttpMethod.Post, "/query/{queryName}")]
89-
public async Task<APIGatewayProxyResponse> Post(APIGatewayProxyRequest request, ILambdaContext context, string queryName) =>
95+
public async Task<APIGatewayProxyResponse> Post(
96+
APIGatewayProxyRequest request,
97+
ILambdaContext context,
98+
string queryName) =>
9099
await queryFunction.HandleAsync(queryName, request, context.Logger);
91100
}
92101
}
@@ -153,7 +162,7 @@ Configuration in `serverless.template`:
153162
"Transform": "AWS::Serverless-2016-10-31",
154163
"Description": "An AWS Serverless Application. This template is partially managed by Amazon.Lambda.Annotations (v1.5.0.0).",
155164
"Resources": {
156-
"CommandQuerySampleAWSLambdaCommandHandleGenerated": {
165+
"CommandQuerySampleAWSLambdaCommandPostGenerated": {
157166
"Type": "AWS::Serverless::Function",
158167
"Metadata": {
159168
"Tool": "Amazon.Lambda.Annotations",
@@ -171,7 +180,7 @@ Configuration in `serverless.template`:
171180
"Architectures": [
172181
"x86_64"
173182
],
174-
"Handler": "CommandQuery.Sample.AWSLambda::CommandQuery.Sample.AWSLambda.Command_Handle_Generated::Handle",
183+
"Handler": "CommandQuery.Sample.AWSLambda::CommandQuery.Sample.AWSLambda.Command_Post_Generated::Post",
175184
"Runtime": "dotnet8",
176185
"CodeUri": ".",
177186
"MemorySize": 256,
@@ -284,104 +293,48 @@ Configuration in `serverless.template`:
284293
You can [test](https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.TestUtilities/README.md) your lambdas with the [Amazon.Lambda.TestUtilities](https://www.nuget.org/packages/Amazon.Lambda.TestUtilities) package.
285294

286295
```cs
296+
using System.Text.Json;
287297
using Amazon.Lambda.APIGatewayEvents;
288-
using Amazon.Lambda.Core;
289298
using Amazon.Lambda.TestUtilities;
290299
using CommandQuery.AWSLambda;
291-
using CommandQuery.Sample.Contracts.Queries;
300+
using CommandQuery.Sample.Contracts.Commands;
292301
using FluentAssertions;
293302
using Microsoft.Extensions.DependencyInjection;
294303
using NUnit.Framework;
295304

296305
namespace CommandQuery.Sample.AWSLambda.Tests
297306
{
298-
public class QueryTests
307+
public class CommandTests
299308
{
300-
public class when_using_the_real_function_via_Post
309+
[SetUp]
310+
public void SetUp()
301311
{
302-
[SetUp]
303-
public void SetUp()
304-
{
305-
var serviceCollection = new ServiceCollection();
306-
new Startup().ConfigureServices(serviceCollection);
307-
var serviceProvider = serviceCollection.BuildServiceProvider();
308-
309-
Subject = new Query(serviceProvider.GetRequiredService<IQueryFunction>());
310-
Request = GetRequest("POST", content: "{ \"Id\": 1 }");
311-
Context = new TestLambdaContext();
312-
}
313-
314-
[Test]
315-
public async Task should_work()
316-
{
317-
var result = await Subject.Post(Request, Context, "BarQuery");
318-
var value = result.As<Bar>()!;
319-
320-
value.Id.Should().Be(1);
321-
value.Value.Should().NotBeEmpty();
322-
}
323-
324-
[Test]
325-
public async Task should_handle_errors()
326-
{
327-
var result = await Subject.Post(Request, Context, "FailQuery");
328-
329-
result.ShouldBeError("The query type 'FailQuery' could not be found");
330-
}
312+
var serviceCollection = new ServiceCollection();
313+
new Startup().ConfigureServices(serviceCollection);
314+
var serviceProvider = serviceCollection.BuildServiceProvider();
331315

332-
Query Subject = null!;
333-
APIGatewayProxyRequest Request = null!;
334-
ILambdaContext Context = null!;
316+
Subject = new Command(serviceProvider.GetRequiredService<ICommandFunction>());
317+
Context = new TestLambdaContext();
335318
}
336319

337-
public class when_using_the_real_function_via_Get
320+
[Test]
321+
public async Task should_handle_command()
338322
{
339-
[SetUp]
340-
public void SetUp()
341-
{
342-
var serviceCollection = new ServiceCollection();
343-
new Startup().ConfigureServices(serviceCollection);
344-
var serviceProvider = serviceCollection.BuildServiceProvider();
345-
346-
Subject = new Query(serviceProvider.GetRequiredService<IQueryFunction>());
347-
Request = GetRequest("GET", query: new Dictionary<string, IList<string>> { { "Id", new List<string> { "1" } } });
348-
Context = new TestLambdaContext();
349-
}
350-
351-
[Test]
352-
public async Task should_work()
353-
{
354-
var result = await Subject.Get(Request, Context, "BarQuery");
355-
var value = result.As<Bar>()!;
356-
357-
value.Id.Should().Be(1);
358-
value.Value.Should().NotBeEmpty();
359-
}
360-
361-
[Test]
362-
public async Task should_handle_errors()
363-
{
364-
var result = await Subject.Get(Request, Context, "FailQuery");
365-
366-
result.ShouldBeError("The query type 'FailQuery' could not be found");
367-
}
368-
369-
Query Subject = null!;
370-
APIGatewayProxyRequest Request = null!;
371-
ILambdaContext Context = null!;
323+
var response = await Subject.Post(GetRequest(new FooCommand { Value = "Foo" }), Context, "FooCommand");
324+
response.StatusCode.Should().Be(200);
372325
}
373326

374-
static APIGatewayProxyRequest GetRequest(string method, string? content = null, Dictionary<string, IList<string>>? query = null)
327+
[Test]
328+
public async Task should_handle_errors()
375329
{
376-
var request = new APIGatewayProxyRequest
377-
{
378-
HttpMethod = method,
379-
Body = content,
380-
MultiValueQueryStringParameters = query
381-
};
382-
383-
return request;
330+
var response = await Subject.Post(GetRequest(new FooCommand()), Context, "FooCommand");
331+
response.ShouldBeError("Value cannot be null or empty");
384332
}
333+
334+
static APIGatewayProxyRequest GetRequest(object body) => new() { Body = JsonSerializer.Serialize(body) };
335+
336+
Command Subject = null!;
337+
TestLambdaContext Context = null!;
385338
}
386339
}
387340
```

CommandQuery.AspNetCore.md

Lines changed: 28 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -159,99 +159,46 @@ You can [integration test](https://docs.microsoft.com/en-us/aspnet/core/test/int
159159

160160
```cs
161161
using System.Net;
162-
using System.Text;
163-
using CommandQuery.Sample.Contracts.Queries;
162+
using System.Net.Http.Json;
163+
using CommandQuery.Sample.Contracts.Commands;
164164
using FluentAssertions;
165165
using Microsoft.AspNetCore.Mvc.Testing;
166166
using NUnit.Framework;
167167

168168
namespace CommandQuery.Sample.AspNetCore.Tests
169169
{
170-
public class QueryControllerTests
170+
public class CommandControllerTests
171171
{
172-
public class when_using_the_real_controller_via_Post
172+
[SetUp]
173+
public void SetUp()
174+
{
175+
Factory = new WebApplicationFactory<Program>();
176+
Client = Factory.CreateClient();
177+
}
178+
179+
[TearDown]
180+
public void TearDown()
173181
{
174-
[SetUp]
175-
public void SetUp()
176-
{
177-
Factory = new WebApplicationFactory<Program>();
178-
Client = Factory.CreateClient();
179-
}
180-
181-
[TearDown]
182-
public void TearDown()
183-
{
184-
Client.Dispose();
185-
Factory.Dispose();
186-
}
187-
188-
[Test]
189-
public async Task should_work()
190-
{
191-
var content = new StringContent("{ \"Id\": 1 }", Encoding.UTF8, "application/json");
192-
193-
var result = await Client.PostAsync("/api/query/BarQuery", content);
194-
var value = await result.Content.ReadAsAsync<Bar>();
195-
196-
result.EnsureSuccessStatusCode();
197-
value.Id.Should().Be(1);
198-
value.Value.Should().NotBeEmpty();
199-
}
200-
201-
[Test]
202-
public async Task should_handle_errors()
203-
{
204-
var content = new StringContent("{ \"Id\": 1 }", Encoding.UTF8, "application/json");
205-
206-
var result = await Client.PostAsync("/api/query/FailQuery", content);
207-
208-
result.StatusCode.Should().Be(HttpStatusCode.NotFound);
209-
(await result.Content.ReadAsStringAsync()).Should().BeEmpty();
210-
}
211-
212-
WebApplicationFactory<Program> Factory = null!;
213-
HttpClient Client = null!;
182+
Client.Dispose();
183+
Factory.Dispose();
214184
}
215185

216-
public class when_using_the_real_controller_via_Get
186+
[Test]
187+
public async Task should_handle_command()
217188
{
218-
[SetUp]
219-
public void SetUp()
220-
{
221-
Factory = new WebApplicationFactory<Program>();
222-
Client = Factory.CreateClient();
223-
}
224-
225-
[TearDown]
226-
public void TearDown()
227-
{
228-
Client.Dispose();
229-
Factory.Dispose();
230-
}
231-
232-
[Test]
233-
public async Task should_work()
234-
{
235-
var result = await Client.GetAsync("/api/query/BarQuery?Id=1");
236-
var value = await result.Content.ReadAsAsync<Bar>();
237-
238-
result.EnsureSuccessStatusCode();
239-
value.Id.Should().Be(1);
240-
value.Value.Should().NotBeEmpty();
241-
}
242-
243-
[Test]
244-
public async Task should_handle_errors()
245-
{
246-
var result = await Client.GetAsync("/api/query/FailQuery?Id=1");
247-
248-
result.StatusCode.Should().Be(HttpStatusCode.NotFound);
249-
(await result.Content.ReadAsStringAsync()).Should().BeEmpty();
250-
}
251-
252-
WebApplicationFactory<Program> Factory = null!;
253-
HttpClient Client = null!;
189+
var response = await Client.PostAsJsonAsync("/api/command/FooCommand", new FooCommand { Value = "Foo" });
190+
response.StatusCode.Should().Be(HttpStatusCode.OK);
254191
}
192+
193+
[Test]
194+
public async Task should_handle_errors()
195+
{
196+
var response = await Client.PostAsJsonAsync("/api/command/FooCommand", new FooCommand { Value = "" });
197+
await response.ShouldBeErrorAsync("Value cannot be null or empty");
198+
}
199+
200+
WebApplicationFactory<Program> Factory = null!;
201+
HttpClient Client = null!;
255202
}
256203
}
257204
```

0 commit comments

Comments
 (0)