Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

Represents the **NuGet** versions.

## v5.11.0
- *Enhancement:* Added `AssertorBase.LogMessages` to enable access to the logs captured during execution of the test for assertion purposes. This is intended to be used in conjunction with the existing `ExpectLogContains` expectation to enable additional (more advanced) assertions against the logs.

## v5.10.0
- *Enhancement:* `TestSharedState` updated to enable request-based (isolated) state; with the corresponding `GetHttpRequestId()` method now made public.
- *Enhancement:* Added `ApiTesterBase.AddPreRunAction()`, `AddPostRunBeforeExpectationsAction()`, `AddPostRunAfterExpectationsAction()` and `AddPostRunAction()` to enable the addition of actions to be executed at different stages of the `Run`/`RunAsync` process for every underlying test. This will enable the addition of common pre/post processing logic without having to explicitly add to each test.
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>5.10.0</Version>
<Version>5.11.0</Version>
<LangVersion>preview</LangVersion>
<Authors>Avanade</Authors>
<Company>Avanade</Company>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ public async Task<ActionResultAssertor> RunAsync(Expression<Func<TFunction, Task

await ExpectationsArranger.AssertAsync(logs, ex).ConfigureAwait(false);

return new ActionResultAssertor(Owner, result, ex);
return new ActionResultAssertor(Owner, result, logs, ex);
}

private void CheckRoute(HttpRequest request, string? route, (string? Name, object? Value)[] @params)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public async Task<VoidAssertor> RunAsync(Expression<Func<TFunction, Task>> expre

await ExpectationsArranger.AssertAsync(logs, ex).ConfigureAwait(false);

return new VoidAssertor(Owner, ex);
return new VoidAssertor(Owner, logs, ex);
}

/// <summary>
Expand Down
6 changes: 3 additions & 3 deletions src/UnitTestEx/AspNetCore/HttpTesterBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ protected async Task<HttpResponseMessageAssertor> SendAsync(HttpMethod httpMetho
Owner.ExecutePostRunBeforeExpectationsActions(this);
await AssertExpectationsAsync(res).ConfigureAwait(false);
Owner.ExecutePostRunAfterExpectationsActions(this);
return new HttpResponseMessageAssertor(Owner, res);
return new HttpResponseMessageAssertor(Owner, LastLogs, res);
}
finally
{
Expand Down Expand Up @@ -136,7 +136,7 @@ protected async Task<HttpResponseMessageAssertor> SendAsync(HttpMethod httpMetho
Owner.ExecutePostRunBeforeExpectationsActions(this);
await AssertExpectationsAsync(res).ConfigureAwait(false);
Owner.ExecutePostRunAfterExpectationsActions(this);
return new HttpResponseMessageAssertor(Owner, res);
return new HttpResponseMessageAssertor(Owner, LastLogs, res);
}
finally
{
Expand Down Expand Up @@ -171,7 +171,7 @@ protected async Task<HttpResponseMessageAssertor> SendAsync(HttpMethod httpMetho
Owner.ExecutePostRunBeforeExpectationsActions(this);
await AssertExpectationsAsync(res).ConfigureAwait(false);
Owner.ExecutePostRunAfterExpectationsActions(this);
return new HttpResponseMessageAssertor(Owner, res);
return new HttpResponseMessageAssertor(Owner, LastLogs, res);
}
finally
{
Expand Down
10 changes: 6 additions & 4 deletions src/UnitTestEx/Assertors/ActionResultAssertor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ namespace UnitTestEx.Assertors
/// </summary>
/// <param name="owner">The owning <see cref="TesterBase"/>.</param>
/// <param name="result">The <see cref="IActionResult"/>.</param>
/// <param name="logs">The logs captured during execution.</param>
/// <param name="exception">The <see cref="Exception"/> (if any).</param>
public class ActionResultAssertor(TesterBase owner, IActionResult result, Exception? exception) : AssertorBase<ActionResultAssertor>(owner, exception)
public class ActionResultAssertor(TesterBase owner, IActionResult result, IEnumerable<string?>? logs, Exception? exception) : AssertorBase<ActionResultAssertor>(owner, logs, exception)
{
/// <summary>
/// Gets the <see cref="IActionResult"/>.
Expand Down Expand Up @@ -485,16 +486,17 @@ public ActionResultAssertor AssertJson(string json, params string[] pathsToIgnor
/// </summary>
/// <param name="httpRequest">The optional requesting <see cref="HttpRequest"/> with <see cref="HttpContext"/>; otherwise, will default.</param>
/// <returns>The corresponding <see cref="HttpResponseMessageAssertor"/>.</returns>
public HttpResponseMessageAssertor ToHttpResponseMessageAssertor(HttpRequest? httpRequest = null) => ToHttpResponseMessageAssertor(Owner, Result, httpRequest);
public HttpResponseMessageAssertor ToHttpResponseMessageAssertor(HttpRequest? httpRequest = null) => ToHttpResponseMessageAssertor(Owner, Result, LogMessages, httpRequest);

/// <summary>
/// Converts the <see cref="ValueAssertor{TValue}"/> to an <see cref="HttpResponseMessageAssertor"/>.
/// </summary>
/// <param name="owner">The owning <see cref="TesterBase"/>.</param>
/// <param name="result">The <see cref="IActionResult"/> to convert.</param>
/// <param name="logs">The log messages captured during execution.</param>
/// <param name="httpRequest">The optional requesting <see cref="HttpRequest"/>; otherwise, will default.</param>
/// <returns>The corresponding <see cref="HttpResponseMessageAssertor"/>.</returns>
internal static HttpResponseMessageAssertor ToHttpResponseMessageAssertor(TesterBase owner, IActionResult result, HttpRequest? httpRequest)
internal static HttpResponseMessageAssertor ToHttpResponseMessageAssertor(TesterBase owner, IActionResult result, IEnumerable<string?>? logs, HttpRequest? httpRequest)
{
var sw = Stopwatch.StartNew();
using var ms = new MemoryStream();
Expand All @@ -517,7 +519,7 @@ internal static HttpResponseMessageAssertor ToHttpResponseMessageAssertor(Tester
sw.Stop();
owner.LogHttpResponseMessage(hr, sw);

return new HttpResponseMessageAssertor(owner, hr);
return new HttpResponseMessageAssertor(owner, logs, hr);
}
}
}
10 changes: 8 additions & 2 deletions src/UnitTestEx/Assertors/AssertorBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ namespace UnitTestEx.Assertors
/// Represents the base test assert helper.
/// </summary>
/// <param name="owner">The owning <see cref="TesterBase"/>.</param>
/// <param name="logs">The logs captured during execution.</param>
/// <param name="exception">The <see cref="Exception"/> (if any).</param>
public abstract class AssertorBase(TesterBase owner, Exception? exception)
public abstract class AssertorBase(TesterBase owner, IEnumerable<string?>? logs, Exception? exception)
{
private static List<Func<AssertorBase, ApiError[], bool>>? _assertErrorsExtentions;

Expand All @@ -28,6 +29,11 @@ public abstract class AssertorBase(TesterBase owner, Exception? exception)
/// </summary>
public TesterBase Owner { get; } = owner ?? throw new ArgumentNullException(nameof(owner));

/// <summary>
/// Gets the log messages captured during execution.
/// </summary>
public IEnumerable<string?> LogMessages { get; } = logs ?? [];

/// <summary>
/// Gets the <see cref="System.Exception"/>.
/// </summary>
Expand Down Expand Up @@ -58,7 +64,7 @@ internal void AssertErrorsUsingExtensions(ApiError[] errors)
return;
}

if (!Assertor.TryAreErrorsMatched(errors, Array.Empty<ApiError>(), out var errorMessage))
if (!Assertor.TryAreErrorsMatched(errors, [], out var errorMessage))
Implementor.AssertFail(errorMessage);
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/UnitTestEx/Assertors/AssertorBaseT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ namespace UnitTestEx.Assertors
/// Represents the base test assert helper that distinguishes between <see cref="AssertException"/> and <see cref="AssertSuccess"/>.
/// </summary>
/// <param name="owner">The owning <see cref="TesterBase"/>.</param>
/// <param name="logs">The logs captured during execution.</param>
/// <param name="exception">The <see cref="Exception"/> (if any).</param>
public abstract class AssertorBase<TSelf>(TesterBase owner, Exception? exception) : AssertorBase(owner, exception) where TSelf : AssertorBase<TSelf>
public abstract class AssertorBase<TSelf>(TesterBase owner, IEnumerable<string?>? logs, Exception? exception) : AssertorBase(owner, logs, exception) where TSelf : AssertorBase<TSelf>
{
/// <summary>
/// Asserts that an <see cref="Exception"/> was thrown during execution.
Expand Down
4 changes: 3 additions & 1 deletion src/UnitTestEx/Assertors/HttpResponseMessageAssertor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

using Microsoft.Net.Http.Headers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Mime;
Expand All @@ -13,8 +14,9 @@ namespace UnitTestEx.Assertors
/// Represents the <see cref="HttpResponseMessage"/> test assert helper.
/// </summary>
/// <param name="owner">The owning <see cref="TesterBase"/>.</param>
/// <param name="logs">The log messages captured during execution.</param>
/// <param name="response">The <see cref="HttpResponseMessage"/>.</param>
public class HttpResponseMessageAssertor(TesterBase owner, HttpResponseMessage response) : HttpResponseMessageAssertorBase<HttpResponseMessageAssertor>(owner, response)
public class HttpResponseMessageAssertor(TesterBase owner, IEnumerable<string?>? logs, HttpResponseMessage response) : HttpResponseMessageAssertorBase<HttpResponseMessageAssertor>(owner, logs, response)
{
/// <summary>
/// Asserts the the <see cref="HttpResponseMessageAssertorBase.Response"/> <see cref="HttpResponseMessage.Headers"/> <see cref="HeaderNames.Location"/> matches the <paramref name="expectedUri"/>.
Expand Down
9 changes: 8 additions & 1 deletion src/UnitTestEx/Assertors/HttpResponseMessageAssertorBase.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Avanade. Licensed under the MIT License. See https://github.com/Avanade/UnitTestEx

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Mime;
using UnitTestEx.Abstractions;
Expand All @@ -15,14 +16,20 @@ namespace UnitTestEx.Assertors
/// Initializes a new instance of the <see cref="HttpResponseMessageAssertorBase{TSelf}"/> class.
/// </remarks>
/// <param name="owner">The owning <see cref="TesterBase"/>.</param>
/// <param name="logs">The log messages captured during execution.</param>
/// <param name="response">The <see cref="HttpResponseMessage"/>.</param>
public abstract class HttpResponseMessageAssertorBase(TesterBase owner, HttpResponseMessage response)
public abstract class HttpResponseMessageAssertorBase(TesterBase owner, IEnumerable<string?>? logs, HttpResponseMessage response)
{
/// <summary>
/// Gets the owning <see cref="TesterBase"/>.
/// </summary>
public TesterBase Owner { get; } = owner ?? throw new ArgumentNullException(nameof(owner));

/// <summary>
/// Gets the log messages captured during execution.
/// </summary>
public IEnumerable<string?> LogMessages { get; } = logs ?? [];

/// <summary>
/// Gets the <see cref="HttpResponseMessage"/>.
/// </summary>
Expand Down
3 changes: 2 additions & 1 deletion src/UnitTestEx/Assertors/HttpResponseMessageAssertorBaseT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ namespace UnitTestEx.Assertors
/// Provides the base <see cref="HttpResponseMessage"/> test assert helper capabilities.
/// </summary>
/// <param name="owner">The owning <see cref="TesterBase"/>.</param>
/// <param name="logs">The log messages captured during execution.</param>
/// <param name="response">The <see cref="HttpResponseMessage"/>.</param>
public abstract class HttpResponseMessageAssertorBase<TSelf>(TesterBase owner, HttpResponseMessage response) : HttpResponseMessageAssertorBase(owner, response) where TSelf : HttpResponseMessageAssertorBase<TSelf>
public abstract class HttpResponseMessageAssertorBase<TSelf>(TesterBase owner, IEnumerable<string?>? logs, HttpResponseMessage response) : HttpResponseMessageAssertorBase(owner, logs, response) where TSelf : HttpResponseMessageAssertorBase<TSelf>
{
/// <summary>
/// Asserts that the <see cref="HttpResponseMessage.StatusCode"/> has a successful value between 200 and 299.
Expand Down
9 changes: 6 additions & 3 deletions src/UnitTestEx/Assertors/HttpResponseMessageAssertorT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

using Microsoft.Net.Http.Headers;
using System;
using System.Collections.Generic;
using System.Net.Http;
using UnitTestEx.Abstractions;

Expand All @@ -11,8 +12,9 @@ namespace UnitTestEx.Assertors
/// Represents the <see cref="HttpResponseMessage"/> test assert helper with a specified response <typeparamref name="TValue"/> <see cref="Type"/>.
/// </summary>
/// <param name="owner">The owning <see cref="TesterBase"/>.</param>
/// <param name="logs">The log messages captured during execution.</param>
/// <param name="response">The <see cref="HttpResponseMessage"/>.</param>
public class HttpResponseMessageAssertor<TValue>(TesterBase owner, HttpResponseMessage response) : HttpResponseMessageAssertorBase<HttpResponseMessageAssertor<TValue>>(owner, response)
public class HttpResponseMessageAssertor<TValue>(TesterBase owner, IEnumerable<string?>? logs, HttpResponseMessage response) : HttpResponseMessageAssertorBase<HttpResponseMessageAssertor<TValue>>(owner, logs, response)
{
private TValue? _value;
private bool _valueIsDeserialized;
Expand All @@ -21,9 +23,10 @@ public class HttpResponseMessageAssertor<TValue>(TesterBase owner, HttpResponseM
/// Initializes a new instance of the <see cref="HttpResponseMessageAssertor"/> class.
/// </summary>
/// <param name="owner">The owning <see cref="TesterBase"/>.</param>
/// <param name="logs">The log messages captured during execution.</param>
/// <param name="value">The value already deserialized.</param>
/// <param name="response">The <see cref="HttpResponseMessage"/>.</param>
public HttpResponseMessageAssertor(TesterBase owner, TValue value, HttpResponseMessage response) : this(owner, response)
public HttpResponseMessageAssertor(TesterBase owner, IEnumerable<string?>? logs, TValue value, HttpResponseMessage response) : this(owner, logs, response)
{
_value = value;
_valueIsDeserialized = true;
Expand All @@ -33,7 +36,7 @@ public HttpResponseMessageAssertor(TesterBase owner, TValue value, HttpResponseM
/// Initializes a new instance of the <see cref="HttpResponseMessageAssertor"/> class.
/// </summary>
/// <param name="assertor">The untyped <see cref="HttpResponseMessageAssertor"/>.</param>
internal HttpResponseMessageAssertor(HttpResponseMessageAssertor assertor) : this(assertor.Owner, assertor.Response) { }
internal HttpResponseMessageAssertor(HttpResponseMessageAssertor assertor) : this(assertor.Owner, assertor.LogMessages, assertor.Response) { }

/// <summary>
/// Gets the response content as the deserialized JSON value.
Expand Down
13 changes: 8 additions & 5 deletions src/UnitTestEx/Assertors/HttpResultAssertor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net.Http;
Expand All @@ -16,8 +17,9 @@ namespace UnitTestEx.Assertors
/// </summary>
/// <param name="owner">The owning <see cref="TesterBase"/>.</param>
/// <param name="result">The <see cref="IResult"/>.</param>
/// <param name="logs">The logs captured during execution.</param>
/// <param name="exception">The <see cref="Exception"/> (if any).</param>
public class HttpResultAssertor(TesterBase owner, IResult result, Exception? exception) : AssertorBase<HttpResultAssertor>(owner, exception)
public class HttpResultAssertor(TesterBase owner, IResult result, IEnumerable<string?>? logs, Exception? exception) : AssertorBase<HttpResultAssertor>(owner, logs, exception)
{
/// <summary>
/// Gets the <see cref="IResult"/>.
Expand All @@ -29,16 +31,17 @@ public class HttpResultAssertor(TesterBase owner, IResult result, Exception? exc
/// </summary>
/// <param name="httpRequest">The optional requesting <see cref="HttpRequest"/> with <see cref="HttpContext"/>; otherwise, will default.</param>
/// <returns>The corresponding <see cref="HttpResponseMessageAssertor"/>.</returns>
public HttpResponseMessageAssertor ToHttpResponseMessageAssertor(HttpRequest? httpRequest = null) => ToHttpResponseMessageAssertor(Owner, Result, httpRequest);
public HttpResponseMessageAssertor ToHttpResponseMessageAssertor(HttpRequest? httpRequest = null) => ToHttpResponseMessageAssertor(Owner, Result, LogMessages, httpRequest);

/// <summary>
/// Converts the <see cref="ValueAssertor{TValue}"/> to an <see cref="HttpResponseMessageAssertor"/>.
/// </summary>
/// <param name="owner">The owning <see cref="TesterBase"/>.</param>
/// <param name="result">The <see cref="IResult"/> to convert.</param>
/// <param name="httpRequest">The optional requesting <see cref="HttpRequest"/>; otherwise, will default.</param>
/// <param name="logs">The log messages captured during execution.</param>
/// <param name="httpRequest">The optional requesting <see cref="HttpRequest"/> with <see cref="HttpContext"/>; otherwise, will default.</param>
/// <returns>The corresponding <see cref="HttpResponseMessageAssertor"/>.</returns>
internal static HttpResponseMessageAssertor ToHttpResponseMessageAssertor(TesterBase owner, IResult result, HttpRequest? httpRequest)
internal static HttpResponseMessageAssertor ToHttpResponseMessageAssertor(TesterBase owner, IResult result, IEnumerable<string?>? logs, HttpRequest? httpRequest)
{
var sw = Stopwatch.StartNew();
using var ms = new MemoryStream();
Expand All @@ -61,7 +64,7 @@ internal static HttpResponseMessageAssertor ToHttpResponseMessageAssertor(Tester
sw.Stop();
owner.LogHttpResponseMessage(hr, sw);

return new HttpResponseMessageAssertor(owner, hr);
return new HttpResponseMessageAssertor(owner, logs, hr);
}
}
}
Expand Down
Loading
Loading