---
title: WireMock Runner Example
description: Explore the experimental WireMock runner integration.
moved_from:
  - foundry/aspire-wiremockrunner.md
---

# WireMock Runner Example

Demonstrates WireMock Runner integration with Aspire for container-based API mocking suitable for integration tests and CI/CD environments.

## 📋 Overview

This example uses Forge's experimental `AddWiremockRunner()` extension to serve three mocks from one runner container: two that pull existing WireMock Cloud projects and one, `new-service`, that the AppHost auto-provisions from seed stubs. `PeopleApi` and `AnimalsApi` consume the mocks, and `WireMockRunner.IntegrationTests` runs against them in CI. See [WireMock Runner Hosting](../local-dev/mocking/host-wiremock-runner.md) for the runner's capabilities and [API Mocking](../local-dev/mocking/index.md) for how mocks integrate with Aspire service discovery.

## 🏗️ Architecture

```mermaid
flowchart LR
    Cloud["WireMock Cloud"]
    Seeds["seeds/new-service/stubs.json"]

    subgraph AppHost["Aspire AppHost"]
        ProvPull["wiremock-provision-and-pull"]
        Runner["WireMock Runner Container"]
        Mock1["aspire-wiremockcli :8080"]
        Mock2["people-test :8081"]
        Mock3["new-service :8082"]
        API["PeopleApi"]
        AnimalsAPI["AnimalsApi"]
    end

    Cloud -.->|Provision and Pull| ProvPull
    Seeds -.->|Import| ProvPull
    ProvPull -->|completes| Runner
    Runner --> Mock1
    Runner --> Mock2
    Runner --> Mock3
    API -->|HttpClient| Mock1
    AnimalsAPI -->|HttpClient| Mock3
```

## 🧩 Components

| Project                           | Description                               |
| --------------------------------- | ----------------------------------------- |
| `WireMockRunner.AppHost`          | Aspire orchestration with WireMock Runner |
| `PeopleApi`                       | ASP.NET Core API consuming mock services  |
| `AnimalsApi`                      | ASP.NET Core API consuming seeded mock    |
| `WireMockRunner.ServiceDefaults`  | Shared Aspire service defaults            |
| `WireMockRunner.IntegrationTests` | Integration tests using WireMock Runner   |

## 📂 Project Structure

```
foundry/dotnet/aspire-wiremockrunner/
├── wiremock-runner.sln
├── WireMockRunner.AppHost/
│   ├── AppHost.cs                    # Runner configuration
│   ├── seeds/
│   │   └── new-service/
│   │       └── stubs.json            # Seed stubs (WireMock export format)
│   └── .wiremock/                    # Generated by provision-and-pull
│       ├── .manifest.json
│       ├── .provisioned.json
│       ├── wiremock.yaml
│       ├── aspire-wiremockcli/
│       ├── people-test/
│       └── new-service/
├── PeopleApi/
│   └── Program.cs                    # API using HttpClient with service discovery
├── AnimalsApi/
│   └── Program.cs                    # API consuming seeded new-service mock
├── WireMockRunner.IntegrationTests/
│   └── PeopleApiTests.cs             # Tests using WireMock Runner
└── WireMockRunner.ServiceDefaults/
    └── Extensions.cs                 # Shared Aspire defaults
```

## 🚀 Getting Started

### Prerequisites

- .NET 10.0 SDK
- Aspire 13.x
- Docker Desktop (for WireMock Runner container)
- Node.js / npm (for the WireMock CLI, installed automatically)
- WireMock Cloud account and API token
- Visual Studio 2022 or VS Code

### Configuration

1. **Get WireMock Cloud API Token**:
   - Log in to [WireMock Cloud](https://app.wiremock.cloud)
   - Navigate to **Settings** → **API Tokens**
   - Create or copy an API token

2. **Set API Token**:
   - **Local Development**: Run the AppHost and enter the API token when prompted in the Aspire dashboard
   - **CI/CD**: Set the `WMC_API_TOKEN` environment variable

### Running the Example

```bash
cd foundry/dotnet/aspire-wiremockrunner
dotnet run --project WireMockRunner.AppHost
```

On first run, the `wiremock-provision-and-pull` resource will:

1. Create the `new-service` mock API in WireMock Cloud (idempotent)
2. Import seed stubs from `seeds/new-service/stubs.json`
3. Pull all mock stubs to the `.wiremock/` directory
4. Fix ports in `wiremock.yaml` to match the configured values
5. Start the runner container, which serves all mocks

### Editing Stubs (Inner Loop)

To iterate on mock responses without restarting the entire AppHost:

1. Edit `seeds/new-service/stubs.json` (e.g., add a new animal)
2. In the Aspire dashboard, click **Start** on the `wiremock-provision-and-pull` resource
3. The seed stubs are re-imported, pulled, and the runner container restarts automatically
4. Your API now returns the updated data

### Seed Stub Format

Seed files use the WireMock export format with stable UUIDs for idempotent imports:

```json title="seeds/new-service/stubs.json"
{
  "mappings": [
    {
      "id": "a1b2c3d4-0001-4000-8000-000000000001",
      "name": "Animals",
      "request": { "method": "GET", "url": "/animals" },
      "response": {
        "status": 200,
        "jsonBody": [
          { "name": "dog", "type": "domestic" },
          { "name": "lion", "type": "wild" },
          { "name": "penguin", "type": "wild" },
          { "name": "cat", "type": "domestic" }
        ]
      }
    }
  ]
}
```

## 📡 API Endpoints

The People API provides:

| Endpoint       | Method | Description                  |
| -------------- | ------ | ---------------------------- |
| `/`            | GET    | Hello World                  |
| `/people`      | GET    | List all people (from mock)  |
| `/people/{id}` | GET    | Get person by ID (from mock) |

The Animals API provides:

| Endpoint        | Method | Description                  |
| --------------- | ------ | ---------------------------- |
| `/animals`      | GET    | List all animals (from mock) |
| `/animals/{id}` | GET    | Get animal by ID (from mock) |

The mock services are configured from WireMock Cloud projects:

- **aspire-wiremockcli** (Port 8080): Project ID `k325y` (existing)
- **people-test** (Port 8081): Project ID `dkl1v` (existing)
- **new-service** (Port 8082): Auto-provisioned with seed stubs

## 🧪 Running Integration Tests

The example includes integration tests that demonstrate WireMock Runner usage:

```bash
cd foundry/dotnet/aspire-wiremockrunner
dotnet test
```

These tests:

- Run WireMock Runner in a container
- Configure mock services for testing
- Verify API behavior against mocks
- Work in CI/CD environments (unlike WireMock CLI)

For a feature-by-feature comparison with WireMock CLI hosting, see [Comparison with Other Mocking Approaches](../local-dev/mocking/host-wiremock-runner.md#comparison-with-other-mocking-approaches).

## 🔗 Related Documentation

- [Host WireMock Runner Guide](../local-dev/mocking/host-wiremock-runner.md)
- [SAIFMOCK001 Experimental Diagnostic](../../reference/diagnostics/SAIFMOCK001.md)
- [WireMock CLI Example](aspire-wiremockcli.md)

## 📍 Source Code

**Location:** [`foundry/dotnet/aspire-wiremockrunner/`](https://dev.azure.com/SAIFCorporation/Platform/_git/forge?path=/foundry/dotnet/aspire-wiremockrunner)

## ⚠️ Important Notes

- **Experimental Feature**: WireMock Runner is experimental (`SAIFMOCK001`)
- **Requires Docker**: Container-based mocks require Docker Desktop
- **Seed Stubs**: Use stable UUIDs in `stubs.json` for idempotent imports
- **Inner Loop**: Re-run `wiremock-provision-and-pull` from the dashboard to pick up stub changes — the runner container restarts automatically
- **API Token Required**: WireMock Cloud API token is required for pulling and provisioning mocks

!!! info "Foundry Example: Auto-Cleanup"

    This foundry example automatically **deletes provisioned mock APIs** from WireMock Cloud and removes `.provisioned.json` when the AppHost is stopped (CTRL+C). This prevents orphaned mocks from accumulating across example sessions. Auto-cleanup is **not** a built-in WireMock Runner feature — in regular local development, provisioned mocks persist so they can be shared and pulled by other team members.
