Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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.Logs` 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.
Comment thread
chullybun marked this conversation as resolved.
Outdated

## 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