From 8876c1323a5055b51f6cd0a8dbab143d75e05272 Mon Sep 17 00:00:00 2001
From: Tom Longhurst <30480171+thomhurst@users.noreply.github.com>
Date: Tue, 12 May 2026 00:03:56 +0100
Subject: [PATCH 1/3] feat(mocks): add Mock.HttpClientFactory() helper
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Adds MockHttpClientFactory : IHttpClientFactory backed by one or more
MockHttpHandler instances. Each CreateClient call returns a fresh
non-disposing HttpClient sharing a handler, so captured requests
survive across `using var client = factory.CreateClient()` blocks.
Supports named clients via WithHandler/HandlerFor for typed-client
DI scenarios; unregistered names fall back to the default handler.
Resolves the UX pain raised in #5885 — no more
`Returns(() => new HttpClient(_handler, disposeHandler: false))`
boilerplate or ObjectDisposedException from shared mock client reuse.
---
Directory.Packages.props | 1 +
.../MockHttpClientFactoryTests.cs | 118 ++++++++++++++++++
TUnit.Mocks.Http/MockExtensions.cs | 12 ++
TUnit.Mocks.Http/MockHttpClientFactory.cs | 46 +++++++
TUnit.Mocks.Http/TUnit.Mocks.Http.csproj | 1 +
docs/docs/writing-tests/mocking/http.md | 27 ++++
6 files changed, 205 insertions(+)
create mode 100644 TUnit.Mocks.Http.Tests/MockHttpClientFactoryTests.cs
create mode 100644 TUnit.Mocks.Http/MockHttpClientFactory.cs
diff --git a/Directory.Packages.props b/Directory.Packages.props
index a314f231cb..333f826166 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -38,6 +38,7 @@
+
diff --git a/TUnit.Mocks.Http.Tests/MockHttpClientFactoryTests.cs b/TUnit.Mocks.Http.Tests/MockHttpClientFactoryTests.cs
new file mode 100644
index 0000000000..8c52b9e6c7
--- /dev/null
+++ b/TUnit.Mocks.Http.Tests/MockHttpClientFactoryTests.cs
@@ -0,0 +1,118 @@
+using System.Net;
+using TUnit.Mocks;
+using TUnit.Mocks.Http;
+
+namespace TUnit.Mocks.Http.Tests;
+
+public class MockHttpClientFactoryTests
+{
+ [Test]
+ public async Task CreateClient_ReturnsConfiguredResponseFromDefaultHandler()
+ {
+ var factory = Mock.HttpClientFactory();
+ factory.Handler.OnGet("/api/users").RespondWithJson("""[{"id":1}]""");
+
+ using var client = factory.CreateClient("any");
+ client.BaseAddress = new Uri("http://localhost");
+
+ var response = await client.GetAsync("/api/users");
+ var body = await response.Content.ReadAsStringAsync();
+
+ await Assert.That(response.StatusCode).IsEqualTo(HttpStatusCode.OK);
+ await Assert.That(body).Contains("id");
+ }
+
+ [Test]
+ public async Task CreateClient_SurvivesUsingBlockDisposal()
+ {
+ var factory = Mock.HttpClientFactory();
+ factory.Handler.OnAnyRequest().Respond(HttpStatusCode.OK);
+
+ for (var i = 0; i < 3; i++)
+ {
+ using var client = factory.CreateClient("default");
+ client.BaseAddress = new Uri("http://localhost");
+ var response = await client.GetAsync("/ping");
+ await Assert.That(response.StatusCode).IsEqualTo(HttpStatusCode.OK);
+ }
+
+ await Assert.That(factory.Handler.Requests).Count().IsEqualTo(3);
+ }
+
+ [Test]
+ public async Task CreateClient_ReturnsFreshInstanceEachCall()
+ {
+ var factory = Mock.HttpClientFactory();
+
+ var a = factory.CreateClient("x");
+ var b = factory.CreateClient("x");
+
+ await Assert.That(a).IsNotSameReferenceAs(b);
+ }
+
+ [Test]
+ public async Task WithHandler_UsesNamedHandlerForMatchingName()
+ {
+ var usersHandler = Mock.HttpHandler();
+ usersHandler.OnGet("/").RespondWithJson("""{"who":"users"}""");
+
+ var ordersHandler = Mock.HttpHandler();
+ ordersHandler.OnGet("/").RespondWithJson("""{"who":"orders"}""");
+
+ var factory = Mock.HttpClientFactory()
+ .WithHandler("users", usersHandler)
+ .WithHandler("orders", ordersHandler);
+
+ using var usersClient = factory.CreateClient("users");
+ usersClient.BaseAddress = new Uri("http://localhost");
+ var usersBody = await (await usersClient.GetAsync("/")).Content.ReadAsStringAsync();
+
+ using var ordersClient = factory.CreateClient("orders");
+ ordersClient.BaseAddress = new Uri("http://localhost");
+ var ordersBody = await (await ordersClient.GetAsync("/")).Content.ReadAsStringAsync();
+
+ await Assert.That(usersBody).Contains("users");
+ await Assert.That(ordersBody).Contains("orders");
+ await Assert.That(usersHandler.Requests).Count().IsEqualTo(1);
+ await Assert.That(ordersHandler.Requests).Count().IsEqualTo(1);
+ }
+
+ [Test]
+ public async Task HandlerFor_FallsBackToDefaultWhenNameNotRegistered()
+ {
+ var factory = Mock.HttpClientFactory();
+
+ var handler = factory.HandlerFor("unregistered");
+
+ await Assert.That(handler).IsSameReferenceAs(factory.Handler);
+ }
+
+ [Test]
+ public async Task Verify_TracksRequestsAcrossMultipleClientLifetimes()
+ {
+ var factory = Mock.HttpClientFactory();
+ factory.Handler.OnGet("/api/data").Respond(HttpStatusCode.OK);
+
+ using (var c1 = factory.CreateClient("default"))
+ {
+ c1.BaseAddress = new Uri("http://localhost");
+ await c1.GetAsync("/api/data");
+ }
+ using (var c2 = factory.CreateClient("default"))
+ {
+ c2.BaseAddress = new Uri("http://localhost");
+ await c2.GetAsync("/api/data");
+ }
+
+ factory.Handler.Verify(r => r.Method(HttpMethod.Get).Path("/api/data"), Times.Exactly(2));
+ }
+
+ [Test]
+ public async Task Constructor_UsesSuppliedDefaultHandler()
+ {
+ var handler = Mock.HttpHandler();
+ var factory = Mock.HttpClientFactory(handler);
+
+ await Assert.That(factory.Handler).IsSameReferenceAs(handler);
+ }
+}
diff --git a/TUnit.Mocks.Http/MockExtensions.cs b/TUnit.Mocks.Http/MockExtensions.cs
index 3e85b77fb7..ad3cf437c4 100644
--- a/TUnit.Mocks.Http/MockExtensions.cs
+++ b/TUnit.Mocks.Http/MockExtensions.cs
@@ -24,5 +24,17 @@ public static class MockExtensions
/// Use .Handler on the returned client to configure setups and verify calls.
///
public static Http.MockHttpClient HttpClient(string baseAddress) => new(baseAddress);
+
+ ///
+ /// Creates a mock backed by a fresh .
+ /// Each CreateClient call returns a new sharing the
+ /// same handler, with handler disposal disabled — safe to use in using blocks.
+ ///
+ public static Http.MockHttpClientFactory HttpClientFactory() => new();
+
+ ///
+ /// Creates a mock backed by the supplied default handler.
+ ///
+ public static Http.MockHttpClientFactory HttpClientFactory(Http.MockHttpHandler handler) => new(handler);
}
}
diff --git a/TUnit.Mocks.Http/MockHttpClientFactory.cs b/TUnit.Mocks.Http/MockHttpClientFactory.cs
new file mode 100644
index 0000000000..480828e4df
--- /dev/null
+++ b/TUnit.Mocks.Http/MockHttpClientFactory.cs
@@ -0,0 +1,46 @@
+namespace TUnit.Mocks.Http;
+
+///
+/// A mock backed by one or more s.
+/// Each call to returns a fresh that
+/// does not dispose the underlying handler, so captured requests survive across using blocks.
+///
+public sealed class MockHttpClientFactory : IHttpClientFactory
+{
+ private readonly Dictionary _named = new(StringComparer.Ordinal);
+
+ /// The default handler used for clients with no name-specific handler configured.
+ public MockHttpHandler Handler { get; }
+
+ /// Creates a factory with a fresh default handler.
+ public MockHttpClientFactory() : this(new MockHttpHandler())
+ {
+ }
+
+ /// Creates a factory using the supplied default handler.
+ public MockHttpClientFactory(MockHttpHandler handler)
+ {
+ Handler = handler;
+ }
+
+ ///
+ /// Register a dedicated handler for a named client. Subsequent
+ /// calls with this name will use the supplied handler.
+ ///
+ public MockHttpClientFactory WithHandler(string name, MockHttpHandler handler)
+ {
+ _named[name] = handler;
+ return this;
+ }
+
+ ///
+ /// Gets the handler associated with the named client, falling back to
+ /// if no name-specific handler has been registered.
+ ///
+ public MockHttpHandler HandlerFor(string name)
+ => _named.TryGetValue(name, out var h) ? h : Handler;
+
+ ///
+ public HttpClient CreateClient(string name)
+ => new(HandlerFor(name), disposeHandler: false);
+}
diff --git a/TUnit.Mocks.Http/TUnit.Mocks.Http.csproj b/TUnit.Mocks.Http/TUnit.Mocks.Http.csproj
index acc90930b1..2bd38e5589 100644
--- a/TUnit.Mocks.Http/TUnit.Mocks.Http.csproj
+++ b/TUnit.Mocks.Http/TUnit.Mocks.Http.csproj
@@ -9,6 +9,7 @@
+
diff --git a/docs/docs/writing-tests/mocking/http.md b/docs/docs/writing-tests/mocking/http.md
index 98aafe00ae..9a7a9432bd 100644
--- a/docs/docs/writing-tests/mocking/http.md
+++ b/docs/docs/writing-tests/mocking/http.md
@@ -237,6 +237,33 @@ Each `CapturedRequest` provides:
| `Matched` | Whether a setup matched this request |
| `Timestamp` | When the request was captured |
+## Mocking `IHttpClientFactory`
+
+When the system under test consumes `IHttpClientFactory` and uses `using var client = factory.CreateClient()`, returning a single shared `HttpClient` will fail on the second call with `ObjectDisposedException`. `Mock.HttpClientFactory()` solves this by returning a fresh non-disposing `HttpClient` per call, all sharing one `MockHttpHandler` so captured requests survive across `using` blocks.
+
+```csharp
+var factory = Mock.HttpClientFactory();
+factory.Handler.OnGet("/api/users").RespondWithJson("""[{"id":1}]""");
+
+var sut = new Sut(factory);
+await sut.DoWork(); // SUT may call CreateClient() any number of times
+
+factory.Handler.Verify(r => r.Method(HttpMethod.Get).Path("/api/users"), Times.Once);
+```
+
+### Named clients
+
+For typed/named clients registered via `services.AddHttpClient("users")`, assign a dedicated handler per name. Unregistered names fall back to `factory.Handler`.
+
+```csharp
+var factory = Mock.HttpClientFactory()
+ .WithHandler("users", Mock.HttpHandler())
+ .WithHandler("orders", Mock.HttpHandler());
+
+factory.HandlerFor("users").OnGet("/").RespondWithJson("""[]""");
+factory.HandlerFor("orders").OnPost("/").Respond(HttpStatusCode.Created);
+```
+
## Reset
```csharp
From 62173e5f9bf36cbbad07bdaf19cc7c0f80b76402 Mon Sep 17 00:00:00 2001
From: Tom Longhurst <30480171+thomhurst@users.noreply.github.com>
Date: Tue, 12 May 2026 00:11:28 +0100
Subject: [PATCH 2/3] refactor(mocks): apply simplify review on
MockHttpClientFactory
- Switch named-handler dictionary to OrdinalIgnoreCase to match
IHttpClientFactory semantics (CreateClient("API") and "api" resolve
the same handler).
- Add WithBaseAddress(string) and WithBaseAddress(name, string) so
factory consumers (and tests) don't have to set BaseAddress on each
produced HttpClient by hand.
- Trim noisy XML docs that narrated WHAT; keep WHY on the class summary.
- Drop low-signal constructor-assignment test; add a name-case-insensitive
test that proves the comparer change.
---
.../MockHttpClientFactoryTests.cs | 50 ++++++++-----------
TUnit.Mocks.Http/MockExtensions.cs | 9 ++--
TUnit.Mocks.Http/MockHttpClientFactory.cs | 47 +++++++++++------
docs/docs/writing-tests/mocking/http.md | 10 ++--
4 files changed, 62 insertions(+), 54 deletions(-)
diff --git a/TUnit.Mocks.Http.Tests/MockHttpClientFactoryTests.cs b/TUnit.Mocks.Http.Tests/MockHttpClientFactoryTests.cs
index 8c52b9e6c7..8757a8b37a 100644
--- a/TUnit.Mocks.Http.Tests/MockHttpClientFactoryTests.cs
+++ b/TUnit.Mocks.Http.Tests/MockHttpClientFactoryTests.cs
@@ -1,20 +1,19 @@
using System.Net;
using TUnit.Mocks;
-using TUnit.Mocks.Http;
namespace TUnit.Mocks.Http.Tests;
public class MockHttpClientFactoryTests
{
+ private const string ClientName = "test-client";
+
[Test]
public async Task CreateClient_ReturnsConfiguredResponseFromDefaultHandler()
{
- var factory = Mock.HttpClientFactory();
+ var factory = Mock.HttpClientFactory().WithBaseAddress("http://localhost");
factory.Handler.OnGet("/api/users").RespondWithJson("""[{"id":1}]""");
- using var client = factory.CreateClient("any");
- client.BaseAddress = new Uri("http://localhost");
-
+ using var client = factory.CreateClient(ClientName);
var response = await client.GetAsync("/api/users");
var body = await response.Content.ReadAsStringAsync();
@@ -25,13 +24,12 @@ public async Task CreateClient_ReturnsConfiguredResponseFromDefaultHandler()
[Test]
public async Task CreateClient_SurvivesUsingBlockDisposal()
{
- var factory = Mock.HttpClientFactory();
+ var factory = Mock.HttpClientFactory().WithBaseAddress("http://localhost");
factory.Handler.OnAnyRequest().Respond(HttpStatusCode.OK);
for (var i = 0; i < 3; i++)
{
- using var client = factory.CreateClient("default");
- client.BaseAddress = new Uri("http://localhost");
+ using var client = factory.CreateClient(ClientName);
var response = await client.GetAsync("/ping");
await Assert.That(response.StatusCode).IsEqualTo(HttpStatusCode.OK);
}
@@ -44,8 +42,8 @@ public async Task CreateClient_ReturnsFreshInstanceEachCall()
{
var factory = Mock.HttpClientFactory();
- var a = factory.CreateClient("x");
- var b = factory.CreateClient("x");
+ var a = factory.CreateClient(ClientName);
+ var b = factory.CreateClient(ClientName);
await Assert.That(a).IsNotSameReferenceAs(b);
}
@@ -60,15 +58,14 @@ public async Task WithHandler_UsesNamedHandlerForMatchingName()
ordersHandler.OnGet("/").RespondWithJson("""{"who":"orders"}""");
var factory = Mock.HttpClientFactory()
+ .WithBaseAddress("http://localhost")
.WithHandler("users", usersHandler)
.WithHandler("orders", ordersHandler);
using var usersClient = factory.CreateClient("users");
- usersClient.BaseAddress = new Uri("http://localhost");
var usersBody = await (await usersClient.GetAsync("/")).Content.ReadAsStringAsync();
using var ordersClient = factory.CreateClient("orders");
- ordersClient.BaseAddress = new Uri("http://localhost");
var ordersBody = await (await ordersClient.GetAsync("/")).Content.ReadAsStringAsync();
await Assert.That(usersBody).Contains("users");
@@ -82,37 +79,34 @@ public async Task HandlerFor_FallsBackToDefaultWhenNameNotRegistered()
{
var factory = Mock.HttpClientFactory();
- var handler = factory.HandlerFor("unregistered");
+ await Assert.That(factory.HandlerFor("unregistered")).IsSameReferenceAs(factory.Handler);
+ }
+
+ [Test]
+ public async Task CreateClient_NameIsCaseInsensitive()
+ {
+ var namedHandler = Mock.HttpHandler();
+ var factory = Mock.HttpClientFactory().WithHandler("Users", namedHandler);
- await Assert.That(handler).IsSameReferenceAs(factory.Handler);
+ await Assert.That(factory.HandlerFor("USERS")).IsSameReferenceAs(namedHandler);
+ await Assert.That(factory.HandlerFor("users")).IsSameReferenceAs(namedHandler);
}
[Test]
public async Task Verify_TracksRequestsAcrossMultipleClientLifetimes()
{
- var factory = Mock.HttpClientFactory();
+ var factory = Mock.HttpClientFactory().WithBaseAddress("http://localhost");
factory.Handler.OnGet("/api/data").Respond(HttpStatusCode.OK);
- using (var c1 = factory.CreateClient("default"))
+ using (var c1 = factory.CreateClient(ClientName))
{
- c1.BaseAddress = new Uri("http://localhost");
await c1.GetAsync("/api/data");
}
- using (var c2 = factory.CreateClient("default"))
+ using (var c2 = factory.CreateClient(ClientName))
{
- c2.BaseAddress = new Uri("http://localhost");
await c2.GetAsync("/api/data");
}
factory.Handler.Verify(r => r.Method(HttpMethod.Get).Path("/api/data"), Times.Exactly(2));
}
-
- [Test]
- public async Task Constructor_UsesSuppliedDefaultHandler()
- {
- var handler = Mock.HttpHandler();
- var factory = Mock.HttpClientFactory(handler);
-
- await Assert.That(factory.Handler).IsSameReferenceAs(handler);
- }
}
diff --git a/TUnit.Mocks.Http/MockExtensions.cs b/TUnit.Mocks.Http/MockExtensions.cs
index ad3cf437c4..5d3e37e828 100644
--- a/TUnit.Mocks.Http/MockExtensions.cs
+++ b/TUnit.Mocks.Http/MockExtensions.cs
@@ -26,15 +26,12 @@ public static class MockExtensions
public static Http.MockHttpClient HttpClient(string baseAddress) => new(baseAddress);
///
- /// Creates a mock backed by a fresh .
- /// Each CreateClient call returns a new sharing the
- /// same handler, with handler disposal disabled — safe to use in using blocks.
+ /// Creates a mock producing non-disposing clients
+ /// that share a , so requests survive using blocks.
///
public static Http.MockHttpClientFactory HttpClientFactory() => new();
- ///
- /// Creates a mock backed by the supplied default handler.
- ///
+ ///
public static Http.MockHttpClientFactory HttpClientFactory(Http.MockHttpHandler handler) => new(handler);
}
}
diff --git a/TUnit.Mocks.Http/MockHttpClientFactory.cs b/TUnit.Mocks.Http/MockHttpClientFactory.cs
index 480828e4df..1cbf94ee7c 100644
--- a/TUnit.Mocks.Http/MockHttpClientFactory.cs
+++ b/TUnit.Mocks.Http/MockHttpClientFactory.cs
@@ -1,46 +1,61 @@
namespace TUnit.Mocks.Http;
///
-/// A mock backed by one or more s.
-/// Each call to returns a fresh that
-/// does not dispose the underlying handler, so captured requests survive across using blocks.
+/// A mock . Each call returns a
+/// fresh with handler disposal disabled, so captured requests on the
+/// shared survive across using blocks.
///
public sealed class MockHttpClientFactory : IHttpClientFactory
{
- private readonly Dictionary _named = new(StringComparer.Ordinal);
+ private readonly Dictionary _named = new(StringComparer.OrdinalIgnoreCase);
+ private readonly Dictionary _baseAddresses = new(StringComparer.OrdinalIgnoreCase);
+ private Uri? _defaultBaseAddress;
- /// The default handler used for clients with no name-specific handler configured.
public MockHttpHandler Handler { get; }
- /// Creates a factory with a fresh default handler.
public MockHttpClientFactory() : this(new MockHttpHandler())
{
}
- /// Creates a factory using the supplied default handler.
public MockHttpClientFactory(MockHttpHandler handler)
{
Handler = handler;
}
- ///
- /// Register a dedicated handler for a named client. Subsequent
- /// calls with this name will use the supplied handler.
- ///
+ /// Register a dedicated handler for a named client.
public MockHttpClientFactory WithHandler(string name, MockHttpHandler handler)
{
_named[name] = handler;
return this;
}
- ///
- /// Gets the handler associated with the named client, falling back to
- /// if no name-specific handler has been registered.
- ///
+ /// Set the base address applied to every result that has no name-specific override.
+ public MockHttpClientFactory WithBaseAddress(string baseAddress)
+ {
+ _defaultBaseAddress = new Uri(baseAddress);
+ return this;
+ }
+
+ /// Set the base address applied to clients created with the specified name.
+ public MockHttpClientFactory WithBaseAddress(string name, string baseAddress)
+ {
+ _baseAddresses[name] = new Uri(baseAddress);
+ return this;
+ }
+
+ /// Gets the handler for the named client, falling back to .
public MockHttpHandler HandlerFor(string name)
=> _named.TryGetValue(name, out var h) ? h : Handler;
///
public HttpClient CreateClient(string name)
- => new(HandlerFor(name), disposeHandler: false);
+ {
+ var client = new HttpClient(HandlerFor(name), disposeHandler: false);
+ var baseAddress = _baseAddresses.TryGetValue(name, out var named) ? named : _defaultBaseAddress;
+ if (baseAddress is not null)
+ {
+ client.BaseAddress = baseAddress;
+ }
+ return client;
+ }
}
diff --git a/docs/docs/writing-tests/mocking/http.md b/docs/docs/writing-tests/mocking/http.md
index 9a7a9432bd..c2cc9bf42e 100644
--- a/docs/docs/writing-tests/mocking/http.md
+++ b/docs/docs/writing-tests/mocking/http.md
@@ -239,10 +239,10 @@ Each `CapturedRequest` provides:
## Mocking `IHttpClientFactory`
-When the system under test consumes `IHttpClientFactory` and uses `using var client = factory.CreateClient()`, returning a single shared `HttpClient` will fail on the second call with `ObjectDisposedException`. `Mock.HttpClientFactory()` solves this by returning a fresh non-disposing `HttpClient` per call, all sharing one `MockHttpHandler` so captured requests survive across `using` blocks.
+`Mock.HttpClientFactory()` returns a factory whose `CreateClient` produces non-disposing `HttpClient`s sharing one `MockHttpHandler`, so captured requests survive `using` blocks in the system under test.
```csharp
-var factory = Mock.HttpClientFactory();
+var factory = Mock.HttpClientFactory().WithBaseAddress("https://api.example.com");
factory.Handler.OnGet("/api/users").RespondWithJson("""[{"id":1}]""");
var sut = new Sut(factory);
@@ -253,12 +253,14 @@ factory.Handler.Verify(r => r.Method(HttpMethod.Get).Path("/api/users"), Times.O
### Named clients
-For typed/named clients registered via `services.AddHttpClient("users")`, assign a dedicated handler per name. Unregistered names fall back to `factory.Handler`.
+For typed/named clients registered via `services.AddHttpClient("users")`, assign a dedicated handler (and optionally base address) per name. Name lookups are case-insensitive, matching `IHttpClientFactory` semantics. Unregistered names fall back to `factory.Handler`.
```csharp
var factory = Mock.HttpClientFactory()
.WithHandler("users", Mock.HttpHandler())
- .WithHandler("orders", Mock.HttpHandler());
+ .WithHandler("orders", Mock.HttpHandler())
+ .WithBaseAddress("users", "https://users.example.com")
+ .WithBaseAddress("orders", "https://orders.example.com");
factory.HandlerFor("users").OnGet("/").RespondWithJson("""[]""");
factory.HandlerFor("orders").OnPost("/").Respond(HttpStatusCode.Created);
From dc7079178fefcd2455040ce3e9bff0acbf455886 Mon Sep 17 00:00:00 2001
From: Tom Longhurst <30480171+thomhurst@users.noreply.github.com>
Date: Tue, 12 May 2026 00:22:04 +0100
Subject: [PATCH 3/3] chore(snapshots): accept reordered ClassTimelineAttribute
in Core net472 public API snapshot
---
...rary_Has_No_API_Changes.Net4_7.verified.txt | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.Net4_7.verified.txt b/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.Net4_7.verified.txt
index f02e58b1e3..64ca32b5e5 100644
--- a/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.Net4_7.verified.txt
+++ b/TUnit.PublicAPI/Tests.Core_Library_Has_No_API_Changes.Net4_7.verified.txt
@@ -228,15 +228,6 @@ namespace
public . OnTestDiscovered(.DiscoveredTestContext context) { }
}
[(.Assembly | .Class)]
- public sealed class ClassTimelineAttribute : .TUnitAttribute, .IScopedAttribute, ., .
- {
- public ClassTimelineAttribute(. mode) { }
- public . Mode { get; }
- public int Order { get; }
- public ScopeType { get; }
- public . OnTestDiscovered(.DiscoveredTestContext context) { }
- }
- [(.Assembly | .Class)]
public class ClassConstructorAttribute : .TUnitAttribute
{
public ClassConstructorAttribute( classConstructorType) { }
@@ -370,6 +361,15 @@ namespace
public static .ClassMetadata GetOrAdd(string name, <.ClassMetadata> factory) { }
public static .ClassMetadata GetOrAdd(string name, .ClassMetadata value) { }
}
+ [(.Assembly | .Class)]
+ public sealed class ClassTimelineAttribute : .TUnitAttribute, .IScopedAttribute, ., .
+ {
+ public ClassTimelineAttribute(. mode) { }
+ public . Mode { get; }
+ public int Order { get; }
+ public ScopeType { get; }
+ public . OnTestDiscovered(.DiscoveredTestContext context) { }
+ }
[(.Class | .Method)]
public sealed class CombinedDataSourcesAttribute : .AsyncUntypedDataSourceGeneratorAttribute
{