RouteStub.Testing 0.0.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package RouteStub.Testing --version 0.0.1
                    
NuGet\Install-Package RouteStub.Testing -Version 0.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="RouteStub.Testing" Version="0.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="RouteStub.Testing" Version="0.0.1" />
                    
Directory.Packages.props
<PackageReference Include="RouteStub.Testing" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add RouteStub.Testing --version 0.0.1
                    
#r "nuget: RouteStub.Testing, 0.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package RouteStub.Testing@0.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=RouteStub.Testing&version=0.0.1
                    
Install as a Cake Addin
#tool nuget:?package=RouteStub.Testing&version=0.0.1
                    
Install as a Cake Tool

Project Scope

Vision

Build a lightweight, convention-based HTTP stub server for .NET.

Instead of defining routes through configuration files or fluent APIs, HTTP requests are resolved directly from a hierarchical collection of stub artifacts. The convention is the configuration.

The goal is to make creating a fake HTTP API as simple as creating folders and files.

For example:

GET /api/weather/sunny

maps to:

stubs/
└── api/
    └── weather/
        └── sunny/
            ├── GET.content.json
            └── GET.response.json

No request mappings. No DSL. No route definitions.

If you know the request URL, you already know where the stub belongs.


Target Audience

The library is intended for developers who need a lightweight HTTP endpoint for:

  • Integration tests
  • Frontend development
  • Local development
  • Console applications
  • Mobile development
  • API prototyping
  • Testing HTTP clients

It should be easy to point any existing HttpClient to the stub server without changing application code.


Design Principles

  • Convention over configuration
  • Real HTTP instead of mocked HttpClient
  • Small and opinionated
  • Fast startup
  • Deterministic request resolution
  • Easy to understand
  • Easy to debug
  • Storage-agnostic architecture

Core Concepts

Convention-based routing

Every URL segment maps directly to a folder.

Static fixtures

Responses are represented as files.

Each endpoint consists of:

  • A content file containing the response body.
  • A response metadata file describing status code, headers, delays, and other HTTP metadata.

Request Resolution

The resolver determines the correct stub by mapping the incoming HTTP request to a hierarchical fixture structure.

The following parts of an HTTP request can influence resolution:

  • HTTP method
  • URL path segments
  • Query parameters
  • Wildcard matching rules

The goal is to make common API variations possible without introducing a configuration language.


Query Parameters

Query parameters are treated as part of the request path when resolving stubs.

Example request:

GET /api/weather?city=London

can resolve to:

stubs/
└── api/
    └── weather/
        └── London/
            ├── GET.content.json
            └── GET.response.json

This allows different responses to be provided for different query parameter combinations while keeping the fixture structure human-readable.


Wildcard Matching

Wildcards are supported to simplify scenarios where exact matching would create unnecessary duplication.

Wildcards are useful for:

  • Dynamic route parameters
  • Variable identifiers
  • Optional query values
  • Groups of similar responses

Example:

Instead of creating:

api/
└── users/
    ├── 123/
    ├── 456/
    └── 789/

a wildcard fixture can be created:

api/
└── users/
    └── *
        ├── GET.content.json
        └── GET.response.json

A request such as:

GET /api/users/123

will resolve against the wildcard fixture.


Resolution Priority

When multiple fixtures could match a request, the resolver prefers the most specific match.

The general priority is:

  1. Exact path match
  2. Wildcard path match

This ensures specific scenarios override generic defaults.

Example:

api/
└── users/
    ├── 123/
    │   └── GET.content.json
    │
    └── *
        └── GET.content.json

Request:

GET /api/users/123

will use:

users/123/

because it is more specific than:

users/*

Architecture

The project consists of a small, reusable resolution engine.

HTTP Request
      │
      ▼
Convention Resolver
      │
      ▼
Stub Repository
      │
      ├── Local filesystem
      ├── Azure Files
      ├── Memory
      └── Future implementations

The resolver should never depend on the storage implementation.

Its only responsibility is resolving an incoming request to the most appropriate stub.


Consumption

The same engine powers multiple hosting models.

  • ASP.NET Core middleware
  • Standalone CLI
  • Test host for integration tests

Every host should behave identically because they all use the same resolver.

ASP.NET Core

Install the ASP.NET Core integration package from NuGet.org:

dotnet add package RouteStub.AspNetCore

Or add the package reference directly when pinning a version in the project file:

<PackageReference Include="RouteStub.AspNetCore" Version="1.0.0" />

For the shortest setup, mount a fixture directory directly after building the application:

using RouteStub.AspNetCore;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.UseStubServer("./stubs");
app.Run();

Use service registration when the fixture path comes from configuration or when the application supplies a custom IStubRepository or IStubResolver:

using RouteStub.AspNetCore;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddStubServer(options =>
{
    options.FixturePath = "./stubs";
});

var app = builder.Build();
app.UseStubServer();
app.Run();

RouteStub adds its filesystem repository and resolver only when the application has not already registered replacements. UseStubServer is terminal middleware, so register authentication, logging, or other middleware that must run for stub requests before it.

Integration tests

Install the framework-neutral testing package from a test project:

dotnet add package RouteStub.Testing

Or add the package reference directly when pinning a version in the project file:

<PackageReference Include="RouteStub.Testing" Version="1.0.0" />

Start a real loopback HTTP endpoint on an available ephemeral port and assign its address to the client under test:

using RouteStub.Testing;

await using var server = await RouteStubTestServer.StartAsync("./stubs");

using var client = new HttpClient
{
    BaseAddress = server.BaseAddress
};

var response = await client.GetAsync("api/weather");

RouteStubTestServer is independent of any test framework. It supports startup cancellation and implements IAsyncDisposable, so it works with the lifecycle conventions of MSTest, xUnit, NUnit, or a custom test harness.

Runnable samples

Complete examples for both integration models are available under samples. The directory contains a dedicated RouteStub.Samples.slnx solution, an ASP.NET Core host with representative fixtures, and an integration test that configures an application HTTP client from an ephemeral RouteStubTestServer endpoint.

dotnet build samples\RouteStub.Samples.slnx
dotnet test samples\RouteStub.Testing.Sample
dotnet run --project samples\RouteStub.AspNetCore.Sample

Standalone server

The CLI can be run directly from this repository. It uses the same middleware adapter as the ASP.NET Core and testing packages.

Run the fixture directory at ./stubs on the default http://localhost:5000 address:

dotnet run --project src/RouteStub.Cli -- serve

Provide a different fixture directory or listening address when needed:

dotnet run --project src/RouteStub.Cli -- serve ./fixtures --url http://localhost:5050

Content files support JSON, XML, HTML, PDF, plain text, CSS, JavaScript, CSV, YAML, PNG, JPEG, GIF, SVG, and WebP. The file extension determines the HTTP Content-Type header.


Publishing a NuGet release

Package publication is performed by publish-nuget.yml when a GitHub Release is published. Maintainers must configure a repository Actions secret named NUGET_API_KEY containing a scoped NuGet.org API key that can create new versions of RouteStub.Core, RouteStub.AspNetCore, RouteStub.Server, and RouteStub.Testing.

Create and publish a GitHub Release with a stable semantic-version tag in exact vMAJOR.MINOR.PATCH form, such as v1.2.3. The workflow validates the tag, restores, builds, and tests the full solution, and then packs all four projects with the normalized 1.2.3 package version. It verifies the resulting package set and same-version dependency graph before any package is pushed to NuGet.org. Branch pushes, pull requests, draft releases, and prerelease-style tags do not publish packages.

NuGet package versions are immutable. If a workflow run stops after publishing only part of the package set, rerun the same release workflow after correcting the failure. Publication uses --skip-duplicate, so packages accepted during the previous attempt are skipped and the remaining packages can be published safely. The API key is supplied only to the final publication step and is not stored in repository files.


Non-Goals

This project is intentionally not trying to replace WireMock.

It will not aim to provide:

  • Complex request matching
  • Configuration-heavy route definitions
  • Recording/proxying
  • Stateful workflows
  • Contract testing
  • JavaScript scripting
  • API virtualization

Those tools already exist.

This project focuses on the 90% use case:

"I need an HTTP endpoint that returns realistic responses with as little setup as possible."


Guiding Principle

If creating or changing a stub requires learning a custom configuration language, the project has failed.

The ideal workflow should be:

  1. Create a folder.
  2. Copy an existing stub.
  3. Modify the response.
  4. Start the server.
  5. Your application works.

Nothing more.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 132 7/18/2026
0.0.1 116 7/17/2026