Skip to content

Commit 2dcf998

Browse files
authored
Resolve issue #18 (#19)
1 parent 1e8f7c2 commit 2dcf998

File tree

9 files changed

+75
-7
lines changed

9 files changed

+75
-7
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
Represents the **NuGet** versions.
44

5+
## v1.0.8
6+
- *[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`.
7+
- *Enhancement:* Write the `Contents` to the test output where the result is `ContentResult`.
8+
59
## v1.0.7
610
- *[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.
711
- *[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.

Common.targets

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project>
22
<PropertyGroup>
3-
<Version>1.0.7</Version>
3+
<Version>1.0.8</Version>
44
<LangVersion>preview</LangVersion>
55
<Authors>Avanade</Authors>
66
<Company>Avanade</Company>

src/UnitTestEx/Assertors/ActionResultAssertor.cs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public ActionResultAssertor Assert(object? expectedValue, params string[] member
8787
else if (Result is JsonResult)
8888
return AssertJsonResult(expectedValue, membersToIgnore);
8989
else if (Result is ContentResult)
90-
return AssertContentResult(expectedValue?.ToString());
90+
return AssertContentResult(expectedValue, membersToIgnore);
9191

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

328329
var cr = (ContentResult)Result;
329-
return AssertValue(expectedValue, cr.Content, Array.Empty<string>());
330+
if (expectedValue != null && cr.Content != null && cr.ContentType == MediaTypeNames.Application.Json)
331+
return AssertValue(expectedValue, JsonConvert.DeserializeObject(cr.Content)!, membersToIgnore);
332+
else
333+
return AssertValue(expectedValue, cr.Content!, membersToIgnore);
330334
}
331335

332336
/// <summary>
333337
/// Assert the value.
334338
/// </summary>
335-
private ActionResultAssertor AssertValue(object? expectedValue, object actualValue, string[] membersToIgnore)
339+
private ActionResultAssertor AssertValue(object? expectedValue, object? actualValue, string[] membersToIgnore)
336340
{
337-
if (expectedValue is JToken jte)
341+
if (expectedValue == null && actualValue == null)
342+
return this;
343+
344+
if (expectedValue is JToken jte && actualValue != null)
338345
{
339346
var jta = JToken.FromObject(actualValue);
340347
if (!JToken.DeepEquals(jte, jta))
341348
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)}");
342349
}
350+
else if (actualValue is JToken jta2 && expectedValue != null)
351+
{
352+
var jte2 = JToken.FromObject(expectedValue);
353+
if (!JToken.DeepEquals(jte2, jta2))
354+
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)}");
355+
}
343356
else if (expectedValue is IComparable)
344357
Implementor.AssertAreEqual(expectedValue, actualValue);
345358
else

src/UnitTestEx/Functions/HttpTriggerTester.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,18 @@ private void LogOutput(HttpRequest? req, object? reqVal, IActionResult res, Exce
176176
if (jr.Value != null)
177177
Implementor.WriteLine(JsonConvert.SerializeObject(jr.Value, Formatting.Indented));
178178
}
179+
else if (res is ContentResult cr)
180+
{
181+
Implementor.WriteLine($"Content: [{cr.ContentType ?? "None"}]");
182+
try
183+
{
184+
Implementor.WriteLine(Newtonsoft.Json.Linq.JToken.Parse(cr.Content).ToString(Formatting.Indented));
185+
}
186+
catch
187+
{
188+
Implementor.WriteLine(cr.Content ?? "<null>");
189+
}
190+
}
179191
}
180192

181193
Implementor.WriteLine("");

tests/UnitTestEx.Function/PersonFunction.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using Newtonsoft.Json;
99
using Microsoft.Extensions.Configuration;
1010
using Microsoft.AspNetCore.Mvc.ModelBinding;
11+
using System.Net.Mime;
1112

1213
namespace UnitTestEx.Function
1314
{
@@ -56,6 +57,14 @@ public async Task<IActionResult> RunWithValue([HttpTrigger(AuthorizationLevel.Fu
5657
log.LogInformation("C# HTTP trigger function processed a request.");
5758
return new OkObjectResult(new { first = person.FirstName, last = person.LastName });
5859
}
60+
61+
[FunctionName("PersonFunctionContent")]
62+
public async Task<IActionResult> RunWithContent([HttpTrigger(AuthorizationLevel.Function, "post", Route = "people/content/{name}")] Person person, ILogger log)
63+
{
64+
await Task.CompletedTask.ConfigureAwait(false);
65+
log.LogInformation("C# HTTP trigger function processed a request.");
66+
return new ContentResult { Content = JsonConvert.SerializeObject(new { first = person.FirstName, last = person.LastName }), ContentType = MediaTypeNames.Application.Json, StatusCode = 200 };
67+
}
5968
}
6069

6170
public class Person

tests/UnitTestEx.Function/ServiceBusFunction.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public Task Run4([ServiceBusTrigger("%Run4QueueName%", Connection = "ServiceBusC
8080
}
8181

8282
[FunctionName("ServiceBusSessionFunction5")]
83-
public Task Run5([ServiceBusTrigger("unittestexsess", Connection = "ServiceBusConnectionString2", IsSessionsEnabled = true)] ServiceBusReceivedMessage message, ServiceBusMessageActions messageActions, ILogger log)
83+
public Task Run5([ServiceBusTrigger("unittestexsess", Connection = "ServiceBusConnectionString", IsSessionsEnabled = true)] ServiceBusReceivedMessage message, ServiceBusMessageActions messageActions, ILogger log)
8484
{
8585
return Task.CompletedTask;
8686
}

tests/UnitTestEx.MSTest.Test/PersonFunctionTest.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,5 +87,15 @@ public void ValueVsHttpRequestObject()
8787
.AssertOK()
8888
.Assert(new { first = "Rachel", last = "Smith" });
8989
}
90+
91+
[TestMethod]
92+
public void ValueVsHttpRequestContent()
93+
{
94+
using var test = FunctionTester.Create<Startup>();
95+
test.HttpTrigger<PersonFunction>()
96+
.Run(f => f.RunWithContent(new Person { FirstName = "Rachel", LastName = "Smith" }, test.Logger))
97+
.AssertOK()
98+
.Assert(new { first = "Rachel", last = "Smith" });
99+
}
90100
}
91101
}

tests/UnitTestEx.NUnit.Test/PersonFunctionTest.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,5 +87,15 @@ public void ValueVsHttpRequestObject()
8787
.AssertOK()
8888
.Assert(new { first = "Rachel", last = "Smith" });
8989
}
90+
91+
[Test]
92+
public void ValueVsHttpRequestContent()
93+
{
94+
using var test = FunctionTester.Create<Startup>();
95+
test.HttpTrigger<PersonFunction>()
96+
.Run(f => f.RunWithContent(new Person { FirstName = "Rachel", LastName = "Smith" }, test.Logger))
97+
.AssertOK()
98+
.Assert(new { first = "Rachel", last = "Smith" });
99+
}
90100
}
91101
}

tests/UnitTestEx.Xunit.Test/PersonFunctionTest.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,5 +90,15 @@ public void ValueVsHttpRequestObject()
9090
.AssertOK()
9191
.Assert(new { first = "Rachel", last = "Smith" });
9292
}
93+
94+
[Fact]
95+
public void ValueVsHttpRequestContent()
96+
{
97+
using var test = CreateFunctionTester<Startup>();
98+
test.HttpTrigger<PersonFunction>()
99+
.Run(f => f.RunWithContent(new Person { FirstName = "Rachel", LastName = "Smith" }, test.Logger))
100+
.AssertOK()
101+
.Assert(new { first = "Rachel", last = "Smith" });
102+
}
93103
}
94104
}

0 commit comments

Comments
 (0)