Skip to content

feat: HttpMock.Aspire.Hosting — first-class Aspire 13 resource for HttpMock stub servers#130

Merged
hibri merged 16 commits intomasterfrom
copilot/evaluate-httpmock-net-aspire
Apr 22, 2026
Merged

feat: HttpMock.Aspire.Hosting — first-class Aspire 13 resource for HttpMock stub servers#130
hibri merged 16 commits intomasterfrom
copilot/evaluate-httpmock-net-aspire

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 17, 2026

Ships HttpMock.Aspire.Hosting, a new NuGet package that registers an HttpMock stub server as a proper Aspire resource. Eliminates manual port allocation, appHost.Configuration[...] overrides, and FindAvailablePort boilerplate from test projects.

New package: HttpMock.Aspire.Hosting (net10.0, Aspire 13.2.2)

  • HttpMockResourceResource + IResourceWithConnectionString + IDisposable. Public Url (read after start) and MockServer (for stub configuration in tests).
  • HttpMockEventingSubscriberIDistributedApplicationEventingSubscriber (Aspire 13 eventing API). Starts the server in BeforeStartEvent, publishes Running state to the dashboard, disposes on teardown.
  • HttpMockResourceBuilderExtensions.AddHttpMock() — single fluent entry point via TryAddEventingSubscriber.
// App host
var mock = builder.AddHttpMock("external-weather-api");
builder.AddProject<Projects.WeatherApi>("weatherapi").WithReference(mock);

// Test — no port bookkeeping, no config overrides
var resource = app.Services.GetRequiredService<DistributedApplicationModel>()
    .Resources.OfType<HttpMockResource>().Single(r => r.Name == "external-weather-api");

resource.MockServer!
    .WithNewContext()
    .Stub(x => x.Get("/api/weather"))
    .Return(json).AsContentType("application/json").OK();

HttpMockRepository.FindFreePort() — consolidated port allocation

Replaced the ad-hoc lsof-based PortHelper.FindLocalAvailablePortForTesting() and the private FindFreePort() in HttpMockEventingSubscriber with a single public TcpListener(port 0) implementation on HttpMockRepository. Both former callers now delegate to it.

New test projects

  • HttpMock.Aspire.Hosting.Tests — 5 unit/subscriber tests; in-process, no DCP required. Subscriber test fires BeforeStartEvent directly via a CapturingEventing test double.
  • HttpMock.Aspire.Hosting.IntegrationTests.AppHost — minimal Aspire.AppHost.Sdk host registering AddHttpMock("mock-api").
  • HttpMock.Aspire.Hosting.IntegrationTests — full lifecycle via Aspire.Hosting.Testing: start → stub → real HTTP calls. Covers GET/POST, JSON, status codes, WithNewContext isolation, and connection-string expression.

Updated

  • examples/AspireExample — AppHost and tests use AddHttpMock/WithReference; README.md updated.
  • Root README.md — new Finding a Free Port and .NET Aspire Integration sections replace the stale manual example.
  • publish.yml — packs HttpMock.Aspire.Hosting on release alongside existing packages.

Copilot AI and others added 5 commits April 17, 2026 13:44
…ting subscriber, and fluent extension

Agent-Logs-Url: https://github.com/hibri/HttpMock/sessions/140eba6b-a97a-4bd8-841f-9781fddde147

Co-authored-by: hibri <122442+hibri@users.noreply.github.com>
…ockServer null guard

Agent-Logs-Url: https://github.com/hibri/HttpMock/sessions/140eba6b-a97a-4bd8-841f-9781fddde147

Co-authored-by: hibri <122442+hibri@users.noreply.github.com>
Agent-Logs-Url: https://github.com/hibri/HttpMock/sessions/140eba6b-a97a-4bd8-841f-9781fddde147

Co-authored-by: hibri <122442+hibri@users.noreply.github.com>
…rt(); make HttpMockResource.Url public

Agent-Logs-Url: https://github.com/hibri/HttpMock/sessions/140eba6b-a97a-4bd8-841f-9781fddde147

Co-authored-by: hibri <122442+hibri@users.noreply.github.com>
…nd integration-test link

Agent-Logs-Url: https://github.com/hibri/HttpMock/sessions/d77ab419-5192-490c-8f7d-aa086b54ff9f

Co-authored-by: hibri <122442+hibri@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class .NET Aspire Hosting integration for HttpMock by introducing a new HttpMock.Aspire.Hosting package that registers and manages HttpMock stub servers as Aspire resources, plus consolidates free-port selection into the core library.

Changes:

  • Introduces HttpMock.Aspire.Hosting package with HttpMockResource, HttpMockEventingSubscriber, and AddHttpMock() builder extension.
  • Adds HttpMockRepository.FindFreePort() and updates test helpers to use it instead of ad-hoc port probing.
  • Adds unit + integration test projects for the Aspire hosting integration and updates the Aspire example + README guidance.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/HttpMock/HttpMockRepository.cs Adds FindFreePort() helper to centralize port allocation.
src/HttpMock.Integration.Tests/PortHelper.cs Replaces custom port probing with HttpMockRepository.FindFreePort().
src/HttpMock.Aspire.Hosting/HttpMockResourceBuilderExtensions.cs Adds AddHttpMock() fluent registration entry point for app hosts.
src/HttpMock.Aspire.Hosting/HttpMockResource.cs Defines Aspire resource model for an HttpMock server (URL + server handle + connection string expression).
src/HttpMock.Aspire.Hosting/HttpMockEventingSubscriber.cs Starts/stops HttpMock servers via Aspire lifecycle eventing and publishes resource state/URL.
src/HttpMock.Aspire.Hosting/HttpMock.Aspire.Hosting.csproj New packable project for Aspire hosting integration.
src/HttpMock.Aspire.Hosting.Tests/HttpMockResourceTests.cs Unit + in-process subscriber tests for the new Aspire resource.
src/HttpMock.Aspire.Hosting.Tests/HttpMock.Aspire.Hosting.Tests.csproj New test project for the Aspire hosting integration.
src/HttpMock.Aspire.Hosting.IntegrationTests/HttpMockResourceIntegrationTests.cs End-to-end lifecycle tests using Aspire.Hosting.Testing.
src/HttpMock.Aspire.Hosting.IntegrationTests/HttpMock.Aspire.Hosting.IntegrationTests.csproj New integration test project referencing the AppHost + hosting package.
src/HttpMock.Aspire.Hosting.IntegrationTests.AppHost/HttpMock.Aspire.Hosting.IntegrationTests.AppHost.csproj Minimal Aspire AppHost used by integration tests.
src/HttpMock.Aspire.Hosting.IntegrationTests.AppHost/AppHost.cs Registers AddHttpMock("mock-api") in the test AppHost.
examples/AspireExample/README.md Updates example docs to use AddHttpMock and resource-based stubbing.
examples/AspireExample/AspireExample.Tests/IntegrationTest1.cs Updates example tests to discover HttpMockResource and configure stubs via MockServer.
examples/AspireExample/AspireExample.Tests/AspireExample.Tests.csproj Switches example test dependency to HttpMock.Aspire.Hosting and adds required usings.
examples/AspireExample/AspireExample.AppHost/AspireExample.AppHost.csproj References HttpMock.Aspire.Hosting as a non-resource dependency.
examples/AspireExample/AspireExample.AppHost/AppHost.cs Registers HttpMock as a first-class Aspire resource instead of a connection string override.
README.md Replaces stale Aspire instructions with new HttpMock.Aspire.Hosting guidance + FindFreePort() section.
HttpMock.sln Adds new projects to the solution and extends configurations.
.github/workflows/publish.yml Packs and publishes the new HttpMock.Aspire.Hosting package on release.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/HttpMock.Integration.Tests/PortHelper.cs Outdated
Comment thread src/HttpMock/HttpMockRepository.cs Outdated
/// resource.MockServer.WithNewContext().Stub(x => x.Get("/path")).Return("body").OK();
/// </code>
/// </summary>
public IHttpServer? MockServer { get; internal set; }
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Import the HttpMock namespace

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using HttpMock; was already added to HttpMockResource.cs in d7b4765 (line 2). No further changes needed.

Comment on lines +34 to +38
var port = HttpMockRepository.FindFreePort();
var url = $"http://localhost:{port}";

resource.Url = url;
resource.MockServer = new HttpServer(new Uri(url));
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in d7b4765. Added explicit using HttpMock; to HttpMockEventingSubscriber.cs, HttpMockResource.cs, and HttpMockResourceTests.cs. Also replaced the hard-coded port 59998 in the Dispose_ClearsMockServerProperty test with HttpMockRepository.FindFreePort() so it can't collide with other tests or processes.

public void Dispose_ClearsMockServerProperty()
{
var resource = new HttpMockResource("test");
resource.MockServer = HttpMockRepository.At("http://localhost:59998");
hibri and others added 2 commits April 17, 2026 16:25
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
} No newline at end of file
namespace HttpMock.Integration.Tests
{
internal static class PortHelper
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot remove the PortHelper class and update its usages with HttpMock.HttpMockRepository.FindFreePort();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 661bcb1. Deleted PortHelper.cs and updated HostHelper.cs and HttpServerTests.cs to call HttpMockRepository.FindFreePort() directly.

Copilot AI requested a review from hibri April 21, 2026 19:22
@hibri hibri marked this pull request as ready for review April 22, 2026 18:57
@hibri hibri merged commit e8acabe into master Apr 22, 2026
1 check passed
@hibri hibri deleted the copilot/evaluate-httpmock-net-aspire branch April 22, 2026 19:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants