Skip to content

Commit

Permalink
Merge pull request #22 from martincostello/UX-Improvements
Browse files Browse the repository at this point in the history
UX Improvements
  • Loading branch information
martincostello authored Nov 9, 2019
2 parents 178ed17 + f2d98e1 commit d00f23e
Show file tree
Hide file tree
Showing 15 changed files with 86 additions and 45 deletions.
4 changes: 2 additions & 2 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@
<SignAssembly>true</SignAssembly>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<AssemblyVersion>0.2.0.0</AssemblyVersion>
<VersionPrefix>0.2.2</VersionPrefix>
<AssemblyVersion>0.3.0.0</AssemblyVersion>
<VersionPrefix>0.3.0</VersionPrefix>
<VersionSuffix Condition=" '$(VersionSuffix)' == '' AND '$(APPVEYOR)' == 'true' AND '$(APPVEYOR_REPO_TAG)' != 'true'">beta$([System.Convert]::ToInt32(`$(APPVEYOR_BUILD_NUMBER)`).ToString(`0000`))</VersionSuffix>
<VersionSuffix Condition=" '$(VersionSuffix)' == '' AND '$(TF_BUILD)' == 'True'">beta$([System.Convert]::ToInt32(`$(BUILD_BUILDID)`).ToString(`0000`))</VersionSuffix>
<VersionSuffix Condition=" '$(VersionSuffix)' == '' AND '$(TRAVIS)' == 'true'">beta$([System.Convert]::ToInt32(`$(TRAVIS_BUILD_NUMBER)`).ToString(`0000`))</VersionSuffix>
Expand Down
22 changes: 6 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ Here's an example using xunit to verify that `ReverseFunction` works as intended

```csharp
using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MartinCostello.Testing.AwsLambdaTestServer;
Expand Down Expand Up @@ -101,11 +100,9 @@ namespace MyFunctions

// Assert
Assert.True(context.Response.TryRead(out LambdaTestResponse response));
Assert.NotNull(response);
Assert.True(response.IsSuccessful);
Assert.NotNull(response.Content);

json = Encoding.UTF8.GetString(response.Content);
json = await response.ReadAsStringAsync();
int[] actual = JsonConvert.DeserializeObject<int[]>(json);

Assert.Equal(new[] { 3, 2, 1 }, actual);
Expand All @@ -123,6 +120,8 @@ The key parts to call out here are:
1. Once the function processing completes after the `CancellationToken` is signalled, the channel reader is read to obtain the `LambdaTestResponse` for the request that was enqueued.
1. Once this is returned from the channel reader, the response is checked for success using `IsSuccessful` and then the `Content` (which is a `byte[]`) is deserialized into the expected response to be asserted on. Again, you could make your own extensions to deserialize the response content into `string` or objects from JSON.

The library itself targets `netcoreapp3.0` so requires your test project to target at least .NET Core 3.0, but the function you're testing could target a previous version such as .NET Core 2.2.

### Examples

You can find examples of how to factor your Lambda function and how to test it:
Expand All @@ -141,7 +140,6 @@ An example of providing these values from an xunit test is shown below:

```csharp
using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MartinCostello.Testing.AwsLambdaTestServer;
Expand Down Expand Up @@ -180,11 +178,9 @@ namespace MyFunctions

// Assert
Assert.True(context.Response.TryRead(out LambdaTestResponse response));
Assert.NotNull(response);
Assert.True(response.IsSuccessful);
Assert.NotNull(response.Content);

json = Encoding.UTF8.GetString(response.Content);
json = await response.ReadAsStringAsync();
int[] actual = JsonConvert.DeserializeObject<int[]>(json);

Assert.Equal(new[] { 3, 2, 1 }, actual);
Expand All @@ -205,7 +201,6 @@ An example of this customisation for an xunit test is shown below:

```csharp
using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MartinCostello.Testing.AwsLambdaTestServer;
Expand Down Expand Up @@ -244,11 +239,9 @@ namespace MyFunctions

// Assert
Assert.True(context.Response.TryRead(out LambdaTestResponse response));
Assert.NotNull(response);
Assert.True(response.IsSuccessful);
Assert.NotNull(response.Content);

json = Encoding.UTF8.GetString(response.Content);
json = await response.ReadAsStringAsync();
int[] actual = JsonConvert.DeserializeObject<int[]>(json);

Assert.Equal(new[] { 3, 2, 1 }, actual);
Expand All @@ -265,7 +258,6 @@ Here's an example of configuring the test server to route its logs to xunit usin

```csharp
using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MartinCostello.Logging.XUnit;
Expand Down Expand Up @@ -311,11 +303,9 @@ namespace MartinCostello.Testing.AwsLambdaTestServer

// Assert
Assert.True(context.Response.TryRead(out LambdaTestResponse response));
Assert.NotNull(response);
Assert.True(response.IsSuccessful);
Assert.NotNull(response.Content);

json = Encoding.UTF8.GetString(response.Content);
json = await response.ReadAsStringAsync();
int[] actual = JsonConvert.DeserializeObject<int[]>(json);

Assert.Equal(new[] { 3, 2, 1 }, actual);
Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
os: Visual Studio 2019
version: 0.2.2.{build}
version: 0.3.0.{build}

environment:
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
Expand Down
3 changes: 1 addition & 2 deletions samples/MathsFunctions.Tests/MathsFunctionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.

using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MartinCostello.Testing.AwsLambdaTestServer;
Expand Down Expand Up @@ -41,7 +40,7 @@ public static async Task Function_Computes_Results(double left, string op, doubl
Assert.True(context.Response.TryRead(out var response));
Assert.True(response.IsSuccessful);

json = Encoding.UTF8.GetString(response.Content);
json = await response.ReadAsStringAsync();
var actual = JsonConvert.DeserializeObject<MathsResponse>(json);

Assert.Equal(expected, actual.Result);
Expand Down
41 changes: 41 additions & 0 deletions src/AwsLambdaTestServer/LambdaTestResponseExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (c) Martin Costello, 2019. All rights reserved.
// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.

using System;
using System.ComponentModel;
using System.IO;
using System.Threading.Tasks;

namespace MartinCostello.Testing.AwsLambdaTestServer
{
/// <summary>
/// A class containing extension methods for the <see cref="LambdaTestResponse"/> class. This class cannot be inherited.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public static class LambdaTestResponseExtensions
{
/// <summary>
/// Reads the content of the specified response as a string as an asynchronous operation.
/// </summary>
/// <param name="response">The response to read as a string.</param>
/// <returns>
/// A <see cref="Task{TResult}"/> representing the asynchronous operation to
/// read the content of the specified response as a <see langword="string"/>.
/// </returns>
/// <exception cref="ArgumentNullException">
/// <paramref name="response"/> is <see langword="null"/>.
/// </exception>
public static async Task<string> ReadAsStringAsync(this LambdaTestResponse response)
{
if (response == null)
{
throw new ArgumentNullException(nameof(response));
}

using var stream = new MemoryStream(response.Content);
using var reader = new StreamReader(stream);

return await reader.ReadToEndAsync().ConfigureAwait(false);
}
}
}
2 changes: 2 additions & 0 deletions src/AwsLambdaTestServer/PublicAPI.Shipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ MartinCostello.Testing.AwsLambdaTestServer.LambdaTestResponse
MartinCostello.Testing.AwsLambdaTestServer.LambdaTestResponse.Content.get -> byte[]
MartinCostello.Testing.AwsLambdaTestServer.LambdaTestResponse.Duration.get -> System.TimeSpan
MartinCostello.Testing.AwsLambdaTestServer.LambdaTestResponse.IsSuccessful.get -> bool
MartinCostello.Testing.AwsLambdaTestServer.LambdaTestResponseExtensions
MartinCostello.Testing.AwsLambdaTestServer.LambdaTestServer
MartinCostello.Testing.AwsLambdaTestServer.LambdaTestServer.CreateClient() -> System.Net.Http.HttpClient
MartinCostello.Testing.AwsLambdaTestServer.LambdaTestServer.Dispose() -> void
Expand Down Expand Up @@ -44,6 +45,7 @@ MartinCostello.Testing.AwsLambdaTestServer.LambdaTestServerOptions.LogGroupName.
MartinCostello.Testing.AwsLambdaTestServer.LambdaTestServerOptions.LogGroupName.set -> void
MartinCostello.Testing.AwsLambdaTestServer.LambdaTestServerOptions.LogStreamName.get -> string
MartinCostello.Testing.AwsLambdaTestServer.LambdaTestServerOptions.LogStreamName.set -> void
static MartinCostello.Testing.AwsLambdaTestServer.LambdaTestResponseExtensions.ReadAsStringAsync(this MartinCostello.Testing.AwsLambdaTestServer.LambdaTestResponse response) -> System.Threading.Tasks.Task<string>
static MartinCostello.Testing.AwsLambdaTestServer.LambdaTestServer.ClearLambdaEnvironmentVariables() -> void
static MartinCostello.Testing.AwsLambdaTestServer.LambdaTestServerExtensions.EnqueueAsync(this MartinCostello.Testing.AwsLambdaTestServer.LambdaTestServer server, byte[] content) -> System.Threading.Tasks.Task<MartinCostello.Testing.AwsLambdaTestServer.LambdaTestContext>
static MartinCostello.Testing.AwsLambdaTestServer.LambdaTestServerExtensions.EnqueueAsync(this MartinCostello.Testing.AwsLambdaTestServer.LambdaTestServer server, string value) -> System.Threading.Tasks.Task<MartinCostello.Testing.AwsLambdaTestServer.LambdaTestContext>
Expand Down
6 changes: 2 additions & 4 deletions tests/AwsLambdaTestServer.Tests/Examples.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.

using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
Expand Down Expand Up @@ -61,11 +60,10 @@ public static async Task Function_Can_Process_Request()
// Assert - The channel reader should have the response available
context.Response.TryRead(out LambdaTestResponse response).ShouldBeTrue("No Lambda response is available.");

response.ShouldNotBeNull("The Lambda response is null.");
response.IsSuccessful.ShouldBeTrue("The Lambda function failed to handle the request.");
response.Content.ShouldNotBeNull("The Lambda function did not return any content.");
response.Content.ShouldNotBeEmpty("The Lambda function did not return any content.");

string responseJson = Encoding.UTF8.GetString(response.Content);
string responseJson = await response.ReadAsStringAsync();
var actual = JsonConvert.DeserializeObject<MyResponse>(responseJson);

actual.Sum.ShouldBe(6, "The Lambda function returned an incorrect response.");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) Martin Costello, 2019. All rights reserved.
// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.

using System;
using System.Threading.Tasks;
using Xunit;

namespace MartinCostello.Testing.AwsLambdaTestServer
{
public static class LambdaTestResponseExtensionsTests
{
[Fact]
public static async Task EnqueueAsync_Validates_Parameters()
{
// Arrange
LambdaTestResponse response = null;

// Act
await Assert.ThrowsAsync<ArgumentNullException>("response", () => response.ReadAsStringAsync());
}
}
}
4 changes: 2 additions & 2 deletions tests/AwsLambdaTestServer.Tests/LambdaTestServerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ void Configure(IServiceCollection services)
response.IsSuccessful.ShouldBeTrue();
response.Content.ShouldNotBeNull();

var deserialized = response.ReadAs<MyResponse>();
var deserialized = await response.ReadAsAsync<MyResponse>();
deserialized.Sum.ShouldBe(expected);
}
}
Expand Down Expand Up @@ -451,7 +451,7 @@ public async Task Can_Use_Custom_Function_Variables()
response.IsSuccessful.ShouldBeTrue();
response.Content.ShouldNotBeNull();

var lambdaContext = response.ReadAs<IDictionary<string, string>>();
var lambdaContext = await response.ReadAsAsync<IDictionary<string, string>>();
lambdaContext.ShouldContainKeyAndValue("AwsRequestId", request.AwsRequestId);
lambdaContext.ShouldContainKeyAndValue("ClientContext", "my-app");
lambdaContext.ShouldContainKeyAndValue("FunctionName", options.FunctionName);
Expand Down
2 changes: 1 addition & 1 deletion tests/AwsLambdaTestServer.Tests/ParallelismTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ private static TaskCompletionSource<int> Assert(

var result = await context.Response.ReadAsync();

var response = result.ReadAs<int[]>();
var response = await result.ReadAsAsync<int[]>();

actual += response[0];
}
Expand Down
5 changes: 1 addition & 4 deletions tests/AwsLambdaTestServer.Tests/ReverseFunctionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.

using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MartinCostello.Testing.AwsLambdaTestServer;
Expand Down Expand Up @@ -34,11 +33,9 @@ public static async Task Function_Reverses_Numbers()

// Assert
Assert.True(context.Response.TryRead(out LambdaTestResponse response));
Assert.NotNull(response);
Assert.True(response.IsSuccessful);
Assert.NotNull(response.Content);

json = Encoding.UTF8.GetString(response.Content);
json = await response.ReadAsStringAsync();
int[] actual = JsonConvert.DeserializeObject<int[]>(json);

Assert.Equal(new[] { 3, 2, 1 }, actual);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.

using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MartinCostello.Testing.AwsLambdaTestServer;
Expand Down Expand Up @@ -41,11 +40,9 @@ public static async Task Function_Reverses_Numbers_With_Custom_Options()

// Assert
Assert.True(context.Response.TryRead(out LambdaTestResponse response));
Assert.NotNull(response);
Assert.True(response.IsSuccessful);
Assert.NotNull(response.Content);

json = Encoding.UTF8.GetString(response.Content);
json = await response.ReadAsStringAsync();
int[] actual = JsonConvert.DeserializeObject<int[]>(json);

Assert.Equal(new[] { 3, 2, 1 }, actual);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.

using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MartinCostello.Logging.XUnit;
Expand Down Expand Up @@ -48,11 +47,9 @@ public async Task Function_Reverses_Numbers_With_Logging()

// Assert
Assert.True(context.Response.TryRead(out LambdaTestResponse response));
Assert.NotNull(response);
Assert.True(response.IsSuccessful);
Assert.NotNull(response.Content);

json = Encoding.UTF8.GetString(response.Content);
json = await response.ReadAsStringAsync();
int[] actual = JsonConvert.DeserializeObject<int[]>(json);

Assert.Equal(new[] { 3, 2, 1 }, actual);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,9 @@ public static async Task Function_Reverses_Numbers_With_Mobile_Sdk()

// Assert
Assert.True(context.Response.TryRead(out LambdaTestResponse response));
Assert.NotNull(response);
Assert.True(response.IsSuccessful);
Assert.NotNull(response.Content);

json = Encoding.UTF8.GetString(response.Content);
json = await response.ReadAsStringAsync();
int[] actual = JsonConvert.DeserializeObject<int[]>(json);

Assert.Equal(new[] { 3, 2, 1 }, actual);
Expand Down
4 changes: 2 additions & 2 deletions tests/AwsLambdaTestServer.Tests/TestExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ internal static async Task<LambdaTestContext> EnqueueAsync<T>(this LambdaTestSer
return await server.EnqueueAsync(json);
}

internal static T ReadAs<T>(this LambdaTestResponse response)
internal static async Task<T> ReadAsAsync<T>(this LambdaTestResponse response)
where T : class
{
string json = System.Text.Encoding.UTF8.GetString(response.Content);
string json = await response.ReadAsStringAsync();
return JsonConvert.DeserializeObject<T>(json);
}
}
Expand Down

0 comments on commit d00f23e

Please sign in to comment.