Mock Alpha

Integration Testing

Switch mock scenarios from your test suite using the X-Mock-Scenario header — no dashboard changes, full parallelization

Integration Testing

Your test suite can tell Mock Alpha which scenario to serve for each request. This lets you test multiple code paths (error handling, retries, timeouts) without touching the dashboard or restarting the server.

The pattern is stateless: each request declares its scenario independently, so parallel tests never collide and test failures leave no dirty state behind.

Scenario resolution order

When a request arrives, Mock Alpha picks a scenario in this order:

  1. Session override — if the request sends X-Mock-Session and you have an active override for that session in the dashboard
  2. X-Mock-Scenario header — the scenario key to serve
  3. ?scenario= query parameter — the scenario key in the URL
  4. Match rules — if no explicit key is set, rules are evaluated in priority order
  5. Default scenario — if no rule matches, the scenario marked as default (or the first one if none is marked)

An explicit key wins, but only if it exists. If you send X-Mock-Scenario or ?scenario= and that key matches a scenario on the endpoint, match rules are skipped. If the key does not match any scenario on the endpoint, resolution falls through to match rules and then the default — so a typo'd or removed scenario key behaves as if no key were sent at all, not as an error. Remove the header while testing rule-based logic.

Android (Kotlin)

Use an interceptor to inject the header before each test, choosing the scenario per test:

// Test build only — one interceptor per test, scenario chosen per test
class MockScenarioInterceptor : Interceptor {
    @Volatile var scenario: String? = null

    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request().newBuilder()
            .header("X-Api-Key", BuildConfig.MOCK_ALPHA_KEY)
            .apply { scenario?.let { header("X-Mock-Scenario", it) } }
            .build()
        return chain.proceed(request)
    }
}

@Before fun setUp() { interceptor.scenario = null }

@Test fun `shows retry banner when the server fails`() {
    interceptor.scenario = "error_500"
    // ...assert the UI shows the retry banner
}

@Test fun `navigates to home after login succeeds`() {
    interceptor.scenario = "success"
    // ...assert navigation
}

iOS (Swift)

Rebuild the session when the scenario changes:

// Test target only — rebuild the session when the scenario changes
enum MockScenario {
    static func session(_ scenario: String?) -> URLSession {
        let config = URLSessionConfiguration.ephemeral
        var headers = ["X-Api-Key": mockAlphaKey]
        if let scenario { headers["X-Mock-Scenario"] = scenario }
        config.httpAdditionalHeaders = headers
        return URLSession(configuration: config)
    }
}

func testShowsRetryBannerOnServerError() async throws {
    let client = ApiClient(session: MockScenario.session("error_500"))
    // ...assert the view model surfaces the retry state
}

func testNavigatesToHomeAfterLoginSucceeds() async throws {
    let client = ApiClient(session: MockScenario.session("success"))
    // ...assert navigation
}

Common scenario keys

Mock Alpha doesn't ship any scenarios by default — every scenario on every endpoint is one you (or an AI agent) create. These keys are just a naming convention the dashboard recognizes for coloring and labeling; using them is optional but makes scenarios easier to scan at a glance:

KeyDescriptionUse in tests
successSuccessful response (2xx)Happy path, normal flow
error_401Unauthorized — invalid or missing tokenToken expiry, permission denied
error_500Server error — temporary faultRetry logic, error UI
timeoutSlow response — pair with delayMs scenario configTimeout handling, spinners

Create scenarios (with any key you like) in the dashboard's Endpoint page, then reference them in tests by name.

Why headers instead of session override

The dashboard's session override is powerful for manual exploration but not for test suites:

AspectHeader (test suites)Session override (dashboard)
Stateless per request✓ Yes✗ Global state
Parallel tests safe✓ Yes✗ Tests collide
Survives test failure✓ Yes✗ Leaves dirty state
ScopePer requestPer X-Mock-Session session

The header approach means a test failure leaves nothing behind — the next test starts clean.

Request body in assertions

Some tests need to verify that the mock served the right scenario. Every response includes the scenario key:

let response = try await client.fetch(...)
let scenarioUsed = response.headers["X-Mock-Scenario"] ?? "default"
XCTAssertEqual(scenarioUsed, "error_401")

Authoring new scenarios

Once you design a test flow, you'll likely need new scenarios (error codes, edge cases) that don't exist yet on the endpoint.

The fastest way is to use the AI agent to author scenarios conversationally. For example:

"For the /payments/charge endpoint, add a scenario where the card is declined. The response should be a 400 with a message 'Card declined' and an error code 'insufficient_funds'."

The agent writes the scenario to the dashboard, and your next test run picks it up immediately.

On this page