Skip to content

Commit

Permalink
Resolve issue #18
Browse files Browse the repository at this point in the history
  • Loading branch information
chullybun committed Feb 23, 2022
1 parent 1e8f7c2 commit 814b323
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 7 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

Represents the **NuGet** versions.

## v1.0.8
- *[Issue 18](https://github.com/Avanade/UnitTestEx/issues/18)*: `ActionResultAssertor.Assert` with object value was not performing correct comparison when result is `ContentResult` and the underlying `ContentType` was `Json`.
- *Enhancement:* Write the `Contents` to the test output where the result is `ContentResult`.

## v1.0.7
- *[Issue 12](https://github.com/Avanade/UnitTestEx/issues/12)*: `ObjectComparer.Assert` added for each test framework that compares two objects and will fail, and report, where there is not a match.
- *[Issue 14](https://github.com/Avanade/UnitTestEx/issues/14)*: Re-introduced [`ServiceBusTriggerTester`](./src/UnitTestEx/Functions/ServiceBusTriggerTester.cs) which manages execution and automatically logs the value associated with the trigger.
Expand Down
2 changes: 1 addition & 1 deletion Common.targets
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<Version>1.0.7</Version>
<Version>1.0.8</Version>
<LangVersion>preview</LangVersion>
<Authors>Avanade</Authors>
<Company>Avanade</Company>
Expand Down
23 changes: 18 additions & 5 deletions src/UnitTestEx/Assertors/ActionResultAssertor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public ActionResultAssertor Assert(object? expectedValue, params string[] member
else if (Result is JsonResult)
return AssertJsonResult(expectedValue, membersToIgnore);
else if (Result is ContentResult)
return AssertContentResult(expectedValue?.ToString());
return AssertContentResult(expectedValue, membersToIgnore);

Implementor.AssertFail($"Result IActionResult Type '{Result.GetType().Name}' must be either '{nameof(JsonResult)}', '{nameof(ObjectResult)}' or {nameof(ContentResult)} to assert its value.");
return this;
Expand Down Expand Up @@ -320,26 +320,39 @@ internal ActionResultAssertor AssertJsonResult(object? expectedValue, params str
/// Asserts that the <see cref="Result"/> is a <see cref="ContentResult"/> that matches the <paramref name="expectedValue"/>.
/// </summary>
/// <param name="expectedValue">The expected value.</param>
/// <param name="membersToIgnore">The members to ignore from the comparison.</param>
/// <returns>The <see cref="ActionResultAssertor"/> to support fluent-style method-chaining.</returns>
internal ActionResultAssertor AssertContentResult(string? expectedValue)
internal ActionResultAssertor AssertContentResult(object? expectedValue, params string[] membersToIgnore)
{
AssertResultType<ContentResult>();

var cr = (ContentResult)Result;
return AssertValue(expectedValue, cr.Content, Array.Empty<string>());
if (expectedValue != null && cr.Content != null && cr.ContentType == MediaTypeNames.Application.Json)
return AssertValue(expectedValue, JsonConvert.DeserializeObject(cr.Content)!, membersToIgnore);
else
return AssertValue(expectedValue, cr.Content!, membersToIgnore);
}

/// <summary>
/// Assert the value.
/// </summary>
private ActionResultAssertor AssertValue(object? expectedValue, object actualValue, string[] membersToIgnore)
private ActionResultAssertor AssertValue(object? expectedValue, object? actualValue, string[] membersToIgnore)
{
if (expectedValue is JToken jte)
if (expectedValue == null && actualValue == null)
return this;

if (expectedValue is JToken jte && actualValue != null)
{
var jta = JToken.FromObject(actualValue);
if (!JToken.DeepEquals(jte, jta))
Implementor.AssertFail($"Expected and Actual JSON are not equal: {Environment.NewLine}Expected =>{Environment.NewLine}{jte?.ToString(Formatting.Indented)}{Environment.NewLine}Actual =>{Environment.NewLine}{jta?.ToString(Formatting.Indented)}");
}
else if (actualValue is JToken jta2 && expectedValue != null)
{
var jte2 = JToken.FromObject(expectedValue);
if (!JToken.DeepEquals(jte2, jta2))
Implementor.AssertFail($"Expected and Actual JSON are not equal: {Environment.NewLine}Expected =>{Environment.NewLine}{jte2?.ToString(Formatting.Indented)}{Environment.NewLine}Actual =>{Environment.NewLine}{jta2?.ToString(Formatting.Indented)}");
}
else if (expectedValue is IComparable)
Implementor.AssertAreEqual(expectedValue, actualValue);
else
Expand Down
12 changes: 12 additions & 0 deletions src/UnitTestEx/Functions/HttpTriggerTester.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,18 @@ private void LogOutput(HttpRequest? req, object? reqVal, IActionResult res, Exce
if (jr.Value != null)
Implementor.WriteLine(JsonConvert.SerializeObject(jr.Value, Formatting.Indented));
}
else if (res is ContentResult cr)
{
Implementor.WriteLine($"Content: [{cr.ContentType ?? "None"}]");
try
{
Implementor.WriteLine(Newtonsoft.Json.Linq.JToken.Parse(cr.Content).ToString(Formatting.Indented));
}
catch
{
Implementor.WriteLine(cr.Content ?? "<null>");
}
}
}

Implementor.WriteLine("");
Expand Down
9 changes: 9 additions & 0 deletions tests/UnitTestEx.Function/PersonFunction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Newtonsoft.Json;
using Microsoft.Extensions.Configuration;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using System.Net.Mime;

namespace UnitTestEx.Function
{
Expand Down Expand Up @@ -56,6 +57,14 @@ public async Task<IActionResult> RunWithValue([HttpTrigger(AuthorizationLevel.Fu
log.LogInformation("C# HTTP trigger function processed a request.");
return new OkObjectResult(new { first = person.FirstName, last = person.LastName });
}

[FunctionName("PersonFunctionContent")]
public async Task<IActionResult> RunWithContent([HttpTrigger(AuthorizationLevel.Function, "post", Route = "people/content/{name}")] Person person, ILogger log)
{
await Task.CompletedTask.ConfigureAwait(false);
log.LogInformation("C# HTTP trigger function processed a request.");
return new ContentResult { Content = JsonConvert.SerializeObject(new { first = person.FirstName, last = person.LastName }), ContentType = MediaTypeNames.Application.Json, StatusCode = 200 };
}
}

public class Person
Expand Down
2 changes: 1 addition & 1 deletion tests/UnitTestEx.Function/ServiceBusFunction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public Task Run4([ServiceBusTrigger("%Run4QueueName%", Connection = "ServiceBusC
}

[FunctionName("ServiceBusSessionFunction5")]
public Task Run5([ServiceBusTrigger("unittestexsess", Connection = "ServiceBusConnectionString2", IsSessionsEnabled = true)] ServiceBusReceivedMessage message, ServiceBusMessageActions messageActions, ILogger log)
public Task Run5([ServiceBusTrigger("unittestexsess", Connection = "ServiceBusConnectionString", IsSessionsEnabled = true)] ServiceBusReceivedMessage message, ServiceBusMessageActions messageActions, ILogger log)
{
return Task.CompletedTask;
}
Expand Down
10 changes: 10 additions & 0 deletions tests/UnitTestEx.MSTest.Test/PersonFunctionTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,15 @@ public void ValueVsHttpRequestObject()
.AssertOK()
.Assert(new { first = "Rachel", last = "Smith" });
}

[TestMethod]
public void ValueVsHttpRequestContent()
{
using var test = FunctionTester.Create<Startup>();
test.HttpTrigger<PersonFunction>()
.Run(f => f.RunWithContent(new Person { FirstName = "Rachel", LastName = "Smith" }, test.Logger))
.AssertOK()
.Assert(new { first = "Rachel", last = "Smith" });
}
}
}
10 changes: 10 additions & 0 deletions tests/UnitTestEx.NUnit.Test/PersonFunctionTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,15 @@ public void ValueVsHttpRequestObject()
.AssertOK()
.Assert(new { first = "Rachel", last = "Smith" });
}

[Test]
public void ValueVsHttpRequestContent()
{
using var test = FunctionTester.Create<Startup>();
test.HttpTrigger<PersonFunction>()
.Run(f => f.RunWithContent(new Person { FirstName = "Rachel", LastName = "Smith" }, test.Logger))
.AssertOK()
.Assert(new { first = "Rachel", last = "Smith" });
}
}
}
10 changes: 10 additions & 0 deletions tests/UnitTestEx.Xunit.Test/PersonFunctionTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,15 @@ public void ValueVsHttpRequestObject()
.AssertOK()
.Assert(new { first = "Rachel", last = "Smith" });
}

[Fact]
public void ValueVsHttpRequestContent()
{
using var test = CreateFunctionTester<Startup>();
test.HttpTrigger<PersonFunction>()
.Run(f => f.RunWithContent(new Person { FirstName = "Rachel", LastName = "Smith" }, test.Logger))
.AssertOK()
.Assert(new { first = "Rachel", last = "Smith" });
}
}
}

0 comments on commit 814b323

Please sign in to comment.