http_server_mock

Start a mock HTTP server, register stubs that describe how it should respond to incoming requests, make real HTTP calls against it from your tests, then inspect the recorded call history to verify what happened.

Pass a runtime adapter from http_server_mock_erlang or http_server_mock_js to new/1 to select the underlying server implementation.

import gleam/http
import http_server_mock
import http_server_mock_erlang  // or http_server_mock_js
import http_server_mock/matcher
import http_server_mock/response
import http_server_mock/stub_builder
import http_server_mock/verify

pub fn my_test() {
  let server =
    http_server_mock.new(http_server_mock_erlang.server())
    |> http_server_mock.start()
    |> http_server_mock.with_stub(
      stub_builder.new()
      |> stub_builder.matching(matcher.new() |> matcher.method(http.Get) |> matcher.path("/ping"))
      |> stub_builder.responding_with(response.ok())
      |> stub_builder.build(),
    )

  // ... make HTTP requests to http_server_mock.base_url(server) ...

  verify.called_times(server, matcher.new() |> matcher.path("/ping"), 1)
  http_server_mock.stop(server)
}

Types

Phantom type re-exported for use in type annotations. A MockServer(NotStarted) has been configured but not yet started.

pub type NotStarted =
  @internal NotStarted

Re-exported for use in type annotations by runtime packages and users.

pub type ServerAdapter =
  server_adapter.ServerAdapter

Phantom type re-exported for use in type annotations. A MockServer(Started) is running and ready to accept requests.

pub type Started =
  @internal Started

Phantom type re-exported for use in type annotations. A MockServer(Stopped) has been shut down and cannot accept requests.

pub type Stopped =
  @internal Stopped

Values

pub fn add_stub(
  mock_server: @internal MockServer(Started),
  stub: types.Stub,
) -> Result(Nil, String)

Registers a stub with the server.

Build a Stub using stub_builder.new() |> stub_builder.matching(...) |> stub_builder.responding_with(...) |> stub_builder.build(), or construct one directly from http_server_mock/types.{Stub}.

Returns Ok(Nil) on success, or Error(reason) if the stub could not be registered.

pub fn base_url(
  mock_server: @internal MockServer(Started),
) -> String

Returns the base URL of the mock server, e.g. "http://localhost:54321".

Append your path to this when constructing request URLs in tests.

pub fn new(
  adapter: server_adapter.ServerAdapter,
) -> @internal MockServer(NotStarted)

Creates a new server with default configuration (random free port).

Pass the adapter from your runtime package — http_server_mock_erlang.server() or http_server_mock_js.server() — then chain start to launch.

let server =
  http_server_mock.new(http_server_mock_erlang.server())
  |> http_server_mock.start()
pub fn recorded_requests(
  mock_server: @internal MockServer(Started),
) -> Result(List(types.RecordedRequest), String)

Returns all requests the server has received since it started (or since the last call to reset_requests or reset).

Each RecordedRequest includes the method, path, query string, headers, body, timestamp, and the ID of the stub that matched it (if any).

pub fn remove_stub(
  mock_server: @internal MockServer(Started),
  id: String,
) -> Nil

Removes the stub with the given ID from the server.

Has no effect if no stub with that ID exists.

pub fn reset(mock_server: @internal MockServer(Started)) -> Nil

Removes all stubs and clears the recorded request history in one call.

pub fn reset_requests(
  mock_server: @internal MockServer(Started),
) -> Nil

Clears the server’s recorded request history.

Useful when you want to assert on requests made during a specific part of a test without including earlier setup requests in the count.

pub fn reset_stubs(
  mock_server: @internal MockServer(Started),
) -> Nil

Removes all registered stubs from the server.

Requests made after this call will return 404 until new stubs are registered.

pub fn start(
  mock_server: @internal MockServer(NotStarted),
) -> @internal MockServer(Started)

Starts the mock HTTP server.

Panics if the server could not be started (for example, if the requested port is already in use).

Call stop when the server is no longer needed.

pub fn stop(
  mock_server: @internal MockServer(Started),
) -> @internal MockServer(Stopped)

Stops the mock server and releases the port it was bound to.

The returned MockServer(Stopped) cannot be passed to any function that requires a running server, making accidental post-stop use a compile error.

pub fn unmatched_requests(
  mock_server: @internal MockServer(Started),
) -> Result(List(types.RecordedRequest), String)

Returns all requests the server received that did not match any registered stub.

Useful for diagnosing test failures: if a request you expected to be handled shows up here, it means no stub matched it — check the matcher configuration.

Each RecordedRequest includes the method, path, query string, headers, body, and timestamp. The matched_stub_id field will always be None for these requests.

pub fn with_port(
  mock_server: @internal MockServer(NotStarted),
  port: Int,
) -> @internal MockServer(NotStarted)

Overrides the port the server will bind to when started.

Prefer the default (port 0) in tests so servers never conflict with each other or with other processes on the machine.

pub fn with_stub(
  mock_server: @internal MockServer(Started),
  stub: types.Stub,
) -> @internal MockServer(Started)

Registers a stub with the server and returns the server for chaining.

Build a Stub with stub_builder and pass it in:

let server =
  http_server_mock.new()
  |> http_server_mock.start()
  |> http_server_mock.with_stub(
    stub_builder.new()
    |> stub_builder.matching(matcher.new() |> matcher.path("/ping"))
    |> stub_builder.responding_with(response.ok())
    |> stub_builder.build(),
  )

Panics on registration failure. Use add_stub if you need to handle the error.

Search Document