Skip to content

Commit 4b5f3f9

Browse files
chullybunCopilotCopilot
authored
v5.10.0 (#102)
* ## 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. - *Enhancement:* `TEntryPoint` methods can now be specified as `static`. - *Enhancement:* `ApiError` added implicit conversion from (`string?`, `string`) tuple to enable simplified usage; e.g. `AssertErrors(("field", "Bad Request"))` versus `AssertErrors(new ApiError("field", "Bad Request"))`. - *Fixed:* Reset `MockHttpClientRequest` internal state when using any `With*` method to ensure correct behavior. * Update src/UnitTestEx/Hosting/EntryPoint.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Eric Sibly [chullybun] <eric@thesiblys.com> * Update src/UnitTestEx/Abstractions/TesterBase.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Eric Sibly [chullybun] <eric@thesiblys.com> * Fix: Replace ExecutePreRunActions with ExecutePostRunActions in HttpTesterBase finally block Agent-Logs-Url: https://github.com/Avanade/UnitTestEx/sessions/aaa8d366-8973-4d7e-9cf4-e99050cedaf0 Co-authored-by: chullybun <12836934+chullybun@users.noreply.github.com> * Correct comment. --------- Signed-off-by: Eric Sibly [chullybun] <eric@thesiblys.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
1 parent 112eaa6 commit 4b5f3f9

30 files changed

+534
-169
lines changed

CHANGELOG.md

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,15 @@
22

33
Represents the **NuGet** versions.
44

5+
## v5.10.0
6+
- *Enhancement:* `TestSharedState` updated to enable request-based (isolated) state; with the corresponding `GetHttpRequestId()` method now made public.
7+
- *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.
8+
- *Enhancement:* `TEntryPoint` methods can now be specified as `static`.
9+
- *Enhancement:* `ApiError` added implicit conversion from (`string?`, `string`) tuple to enable simplified usage; e.g. `AssertErrors(("field", "Bad Request"))` versus `AssertErrors(new ApiError("field", "Bad Request"))`.
10+
- *Fixed:* Reset `MockHttpClientRequest` internal state when using any `With*` method to ensure correct behavior.
11+
512
## v5.9.2
6-
- *Fixed:* The `MockHttpClientRequest` now resets the internal count state when overridding a response to ensure `Verify()` functions correctly.
13+
- *Fixed:* The `MockHttpClientRequest` now resets the internal count state when overriding a response to ensure `Verify()` functions correctly.
714

815
## v5.9.1
916
- *Fixed:* The `MockHttpClientRequest` now caches the response content internally, and creates a new `HttpContent` instance for each request to ensure that the content can be read multiple times across multiple requests (where applicable); avoids potential object disposed error.
@@ -95,10 +102,10 @@ Represents the **NuGet** versions.
95102
- `CreateFunctionTester<TStartup>()` replaced with `FunctionTester.Create<TStartup>()`.
96103

97104
## v4.4.2
98-
- *Fixed*: Updated `System.Text.Json` package depenedency to latest; resolve [Microsoft Security Advisory CVE-2024-43485](https://github.com/advisories/GHSA-8g4q-xg66-9fp4).
105+
- *Fixed*: Updated `System.Text.Json` package dependency to latest; resolve [Microsoft Security Advisory CVE-2024-43485](https://github.com/advisories/GHSA-8g4q-xg66-9fp4).
99106

100107
## v4.4.1
101-
- *Fixed:* Updated all package depenedencies to latest.
108+
- *Fixed:* Updated all package dependencies to latest.
102109

103110
## v4.4.0
104111
- *Enhancement:* Added `ExpectJson` and `ExpectJsonFromResource` to `IValueExpectations` to enable value comparison against the specified (expected) JSON.
@@ -136,7 +143,7 @@ Represents the **NuGet** versions.
136143
- *Fixed:* Removed all dependencies to `Newtonsoft.Json`; a developer will need to explicitly add this dependency and `IJsonSerializer` implementation where applicable.
137144

138145
## v4.0.0
139-
All internal dependecies to `CoreEx` have been removed. This is intended to further generalize the capabilities of `UnitTestEx`; but more importantly, break the circular dependency reference between the two repositories. New `CoreEx.UnitTesting*` packages have been created to extend the `UnitTestEx` capabilities for `CoreEx`.
146+
All internal dependencies to `CoreEx` have been removed. This is intended to further generalize the capabilities of `UnitTestEx`; but more importantly, break the circular dependency reference between the two repositories. New `CoreEx.UnitTesting*` packages have been created to extend the `UnitTestEx` capabilities for `CoreEx`.
140147
- *Enhancement:* All typed value assertions have been named `AssertValue` for consistency; otherwise, `AssertContent` for a simple string comparison.
141148
- *Enhancement:* All JSON-related assertions have been named `AssertJson*` for consistency.
142149
- *Enhancement:* The `CreateServiceBusMessage` methods that accept a generic `T` value have been renamed to `CreateServiceBusMessageFromValue`.
@@ -149,7 +156,7 @@ All internal dependecies to `CoreEx` have been removed. This is intended to furt
149156
The enhancements have been made in a manner to maximize backwards compatibility with previous versions of `UnitTestEx` where possible; however, some breaking changes were unfortunately unavoidable (and made to improve overall). There may be an opportunity for the consuming developer to add extension methods to support the previous naming conventions if desired; note that the next `CoreEx` version (`v3.6.0`) will implement extensions in new `CoreEx.UnitTesting` packages to support existing behaviors (where applicable).
150157

151158
## v3.1.0
152-
- *Enhancement:* Updated all package depenedencies to latest.
159+
- *Enhancement:* Updated all package dependencies to latest.
153160
- *Enhancement:* The `GenericTester` updated to support `IHostStartup` to enable shared host dependency injection configuration.
154161
- *Enhancement:* Added `IEventExpectations<TSelf>` and `ILoggerExpectations<TSelf>` support to `GenericTester` and `ValidationTester`.
155162
- *Enhancement:* Moved the `CreateServiceBusMessage` and related methods from `FunctionTesterBase` up the inheritance hierarchy to `TesterBase<TSelf>` to enable broader usage.
@@ -193,7 +200,7 @@ The enhancements have been made in a manner to maximize backwards compatibility
193200
- *Fixed:* Incorrect package deployment; corrected.
194201

195202
## v2.1.0
196-
- *Enhancement:* Added `TestSetUp.RegisterAutoSetUp` that will automatically throw a `TestSetUpException` where unsuccessful; otherwise, queues the successful output message. This is required as most testing frameworks do not allow for a log write during construction or fuxture set up. The underlying _UnitTestEx_ test classes will automatically log write where entries are discovered in the queue. This will at least ensure one of the underlying tests will output the success output where applicable. Otherwise, to log write explicitly use `TestSetUp.LogAutoSetUpOutputs`.
203+
- *Enhancement:* Added `TestSetUp.RegisterAutoSetUp` that will automatically throw a `TestSetUpException` where unsuccessful; otherwise, queues the successful output message. This is required as most testing frameworks do not allow for a log write during construction or fixture set up. The underlying _UnitTestEx_ test classes will automatically log write where entries are discovered in the queue. This will at least ensure one of the underlying tests will output the success output where applicable. Otherwise, to log write explicitly use `TestSetUp.LogAutoSetUpOutputs`.
197204

198205
## v2.0.0
199206
- *Enhancement:* Updated `CoreEx` dependencies to `2.0.0` as breaking changes were introduced. There are no breaking changes within `UnitTestEx` as a result; primarily related to the key `CoreEx` dependency.
@@ -224,7 +231,7 @@ The enhancements have been made in a manner to maximize backwards compatibility
224231
- *Fixed:* Handle `AggregateException` by using its `InnerException` as the `Exception`.
225232

226233
## v1.0.24
227-
- *Enhancement:* Updated the `ControllerTester` removing the HTTP request capabilies and moving into new `HttpTester`; this creates a more logical split as the latter needs no knowledge of the `Controller`. This new tester is available via `ApiTester.Http().Run(...)`.
234+
- *Enhancement:* Updated the `ControllerTester` removing the HTTP request capabilities and moving into new `HttpTester`; this creates a more logical split as the latter needs no knowledge of the `Controller`. This new tester is available via `ApiTester.Http().Run(...)`.
228235
- *Enhancement:* Added new `UnitTextEx.Expectations` namespace; when added will enable `Expect*` and `Ignore*` pre-execution assertions, that are then executed post `Run`/`RunAsync`. Some testers now also support the specification of a `TResponse` generic `Type` to enable further response value-related expectations.
229236

230237
## v1.0.23
@@ -283,7 +290,7 @@ The enhancements have been made in a manner to maximize backwards compatibility
283290
- *Enhancement:* **Breaking change.** Integrate [`CoreEx`](https://github.com/Avanade/CoreEx/) package which primarily brings [`IJsonSerializer`](https://github.com/Avanade/CoreEx/blob/main/src/CoreEx/Json/IJsonSerializer.cs) functionality to enable configuration of either [`CoreEx.Text.Json.JsonSerializer`](https://github.com/Avanade/CoreEx/blob/main/src/CoreEx/Text/Json/JsonSerializer.cs) (default) or [`CoreEx.Newtonsoft.Json.JsonSerializer`](https://github.com/Avanade/CoreEx/blob/main/src/CoreEx.Newtonsoft/Json/JsonSerializer.cs). The `MockHttpClientFactory`, `ApiTester` and `FunctionTester` have new method `UseJsonSerializer` to individually update from the default. To change the default for all tests then set [`CoreEx.Json.JsonSerializer.Default`](https://github.com/Avanade/CoreEx/blob/main/src/CoreEx/Json/JsonSerializer.cs) to the desired serializer.
284291
- *Enhancement:* Improved the replacement of the `MockHttpClientFactory` with the `ApiTester` and `FunctionTester`. Existing code `test.ConfigureServices(sc => mcf.Replace(sc))` can be replaced with `test.ReplaceHttpClientFactory(mcf)`.
285292
- *Enhancement:* Added `ReplaceSingleton`, `ReplaceScoped` and `ReplaceTransient` methods directly to `ApiTester` and `FunctionTester`. For example, existing code `test.ConfigureServices(sc => sc.ReplaceTransient<XXX>())` can be replaced with `test.ReplaceTransient<XXX>()`.
286-
- *Enhancement:* Added addtional `CreateHttpRequest` overloads to support additional parameters `HttpRequestOptions? requestOptions = null, params IHttpArg[] args` as enabled by `CoreEx`. These enable additional capabilities for the `HttpRequest` query string and headers.
293+
- *Enhancement:* Added additional `CreateHttpRequest` overloads to support additional parameters `HttpRequestOptions? requestOptions = null, params IHttpArg[] args` as enabled by `CoreEx`. These enable additional capabilities for the `HttpRequest` query string and headers.
287294

288295
## v1.0.11
289296
- *[Issue 24](https://github.com/Avanade/UnitTestEx/issues/24)*: Added additional `IServiceCollection.Replace` extension methods to support `ReplaceXxx<T>()` and `ReplaceXxx<T, T>()` to match the standard `AddXxx` methods.
@@ -319,10 +326,10 @@ The enhancements have been made in a manner to maximize backwards compatibility
319326
## v1.0.4
320327
- *[Issue 3](https://github.com/Avanade/UnitTestEx/issues/3)*: Added support for MOQ `Times` struct to verify the number of times a request is made.
321328
- *[Issue 4](https://github.com/Avanade/UnitTestEx/issues/4)*: Added support for MOQ sequences; i.e. multiple different responses.
322-
- *[Issue 5](https://github.com/Avanade/UnitTestEx/issues/5)*: Deleted `MockServiceBus` as the mocking failed to work as intended. This has been replaced by `FunctionTesterBase` methods of `CreateServiceBusMessage`, `CreateServiceBusMessageFromResource` and `CreateServiceBusMessageFromJson`.
329+
- *[Issue 5](https://github.com/Avanade/UnitTestEx/issues/5)*: Delete `MockServiceBus` as the mocking failed to work as intended. This has been replaced by `FunctionTesterBase` methods of `CreateServiceBusMessage`, `CreateServiceBusMessageFromResource` and `CreateServiceBusMessageFromJson`.
323330

324331
## v1.0.3
325-
- *Fixed:* `MockHttpClientFactory.CreateClient` overloads were ambiquous, this has been corrected.
332+
- *Fixed:* `MockHttpClientFactory.CreateClient` overloads were ambiguous, this has been corrected.
326333
- *Fixed:* Resolved logging output challenges between the various test frameworks and `ApiTester` (specifically) to achieve consistent output.
327334
- *Enhancement:* The logging output now includes scope details.
328335
- *Added:* New `MockServiceBus.CreateReceivedMessage` which will mock the `ServiceBusReceivedMessage` and add the passed value as serialized JSON into the `Body` (`BinaryData`).

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>5.9.2</Version>
3+
<Version>5.10.0</Version>
44
<LangVersion>preview</LangVersion>
55
<Authors>Avanade</Authors>
66
<Company>Avanade</Company>

src/UnitTestEx.Azure.ServiceBus/ExtensionMethods.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public static ServiceBusReceivedMessage CreateServiceBusMessageFromValue<T>(this
4141
/// </summary>
4242
/// <typeparam name="TAssembly">The <see cref="Type"/> to infer <see cref="Type.Assembly"/> for the embedded resources.</typeparam>
4343
/// <param name="tester">The <see cref="TesterBase"/>.</param>
44-
/// <param name="resourceName">The embedded resource name (matches to the end of the fully qualifed resource name).</param>
44+
/// <param name="resourceName">The embedded resource name (matches to the end of the fully qualified resource name).</param>
4545
/// <param name="messageModify">Optional <see cref="AmqpAnnotatedMessage"/> modifier than enables the message to be further configured.</param>
4646
/// <returns>The <see cref="ServiceBusReceivedMessage"/>.</returns>
4747
public static ServiceBusReceivedMessage CreateServiceBusMessageFromResource<TAssembly>(this TesterBase tester, string resourceName, Action<AmqpAnnotatedMessage>? messageModify = null)
@@ -51,7 +51,7 @@ public static ServiceBusReceivedMessage CreateServiceBusMessageFromResource<TAss
5151
/// Creates a <see cref="ServiceBusReceivedMessage"/> where the <see cref="ServiceBusMessage.Body"/> <see cref="BinaryData"/> will contain the JSON formatted embedded resource as the content (<see cref="MediaTypeNames.Application.Json"/>).
5252
/// </summary>
5353
/// <param name="tester">The <see cref="TesterBase"/>.</param>
54-
/// <param name="resourceName">The embedded resource name (matches to the end of the fully qualifed resource name).</param>
54+
/// <param name="resourceName">The embedded resource name (matches to the end of the fully qualified resource name).</param>
5555
/// <param name="messageModify">Optional <see cref="AmqpAnnotatedMessage"/> modifier than enables the message to be further configured.</param>
5656
/// <param name="assembly">The <see cref="Assembly"/> that contains the embedded resource; defaults to <see cref="Assembly.GetEntryAssembly()"/>.</param>
5757
/// <returns>The <see cref="ServiceBusReceivedMessage"/>.</returns>

src/UnitTestEx/Abstractions/TestSharedState.cs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ namespace UnitTestEx.Abstractions
1313
/// <summary>
1414
/// Provides a means to share state between the <see cref="TesterBase"/> and the corresponding execution.
1515
/// </summary>
16+
/// <remarks>The <see cref="GetHttpRequestId"/>-based functionality is primarily intended for use with <see cref="AspNetCore.HttpTesterBase"/> and related HTTP testing; however, it is available for any
17+
/// testing where sharing state between the tester and execution is required.
18+
/// <para>Be careful when using this class that data does not cross boundaries where it is scoped, or may be disposed, as this may result in unintended side-effect/consequences.</para></remarks>
1619
public sealed class TestSharedState
1720
{
1821
#if NET9_0_OR_GREATER
@@ -38,7 +41,7 @@ internal TestSharedState() { }
3841
/// <param name="message">The log message.</param>
3942
public void AddLoggerMessage(string? message)
4043
{
41-
var id = GetRequestId();
44+
var id = GetHttpRequestId();
4245

4346
lock (_lock)
4447
{
@@ -54,9 +57,11 @@ public void AddLoggerMessage(string? message)
5457
}
5558

5659
/// <summary>
57-
/// Gets the correlation identifier.
60+
/// Gets the HTTP request correlation identifier.
5861
/// </summary>
59-
private string GetRequestId()
62+
/// <remarks>This identifier is used to correlate log messages and other state information with a specific HTTP request.
63+
/// <para>This is only meaningful within the context of an executing host.</para></remarks>
64+
public string GetHttpRequestId()
6065
{
6166
if (HttpContextAccessor == null || HttpContextAccessor.HttpContext == null)
6267
return string.Empty;
@@ -94,6 +99,29 @@ private string GetRequestId()
9499
/// </summary>
95100
public ConcurrentDictionary<string, object?> StateData { get; } = new ConcurrentDictionary<string, object?>();
96101

102+
/// <summary>
103+
/// Gets the state extension data for the specified <paramref name="requestId"/> that can be used for additional state information (where applicable).
104+
/// </summary>
105+
/// <param name="requestId">The unit testing request identifier.</param>
106+
/// <returns>The state extension data for the specified <paramref name="requestId"/>.</returns>
107+
/// <remarks>A <paramref name="requestId"/> that is <see cref="String.IsNullOrEmpty(string?)"/> will return the <see cref="StateData"/>; i.e. is assumed not to be request-based.</remarks>
108+
public ConcurrentDictionary<string, object?> RequestStateData(string? requestId)
109+
=> string.IsNullOrEmpty(requestId)
110+
? StateData
111+
: StateData.GetOrAdd(requestId, _ => new ConcurrentDictionary<string, object?>()) as ConcurrentDictionary<string, object?> ?? new ConcurrentDictionary<string, object?>();
112+
113+
/// <summary>
114+
/// Removes the state data associated with the specified <paramref name="requestId"/>, if it exists.
115+
/// </summary>
116+
/// <param name="requestId">The unit testing request identifier.</param>
117+
public void RemoveRequestStateData(string? requestId)
118+
{
119+
if (string.IsNullOrEmpty(requestId))
120+
return;
121+
122+
StateData.TryRemove(requestId, out _);
123+
}
124+
97125
/// <summary>
98126
/// Resets the <see cref="TestSharedState"/>.
99127
/// </summary>

0 commit comments

Comments
 (0)