ExOutlines.Backend.Mock (ExOutlines v0.1.0)

Copy Markdown View Source

Deterministic mock backend for testing.

Returns pre-configured responses in sequence, allowing tests to simulate LLM behavior without external dependencies.

Example

# Configure responses
mock = Mock.new([
  {:ok, ~s({"name": "Alice", "age": 30})},
  {:ok, ~s({"name": "Alice", "age": 25})}
])

# Use in tests
{:ok, response} = Mock.call_llm(mock, messages, opts)
# => {:ok, ~s({"name": "Alice", "age": 30})}

Error Simulation

mock = Mock.new([
  {:error, :rate_limited},
  {:ok, ~s({"valid": "json"})}
])

{:error, reason} = Mock.call_llm(mock, messages, opts)
# => {:error, :rate_limited}

Summary

Functions

Create a mock that always returns the same response.

Create a mock that always fails with the given error.

Get the number of times this mock has been called.

Call the mock backend.

Create a new mock backend with pre-configured responses.

Types

response()

@type response() :: {:ok, String.t()} | {:error, term()}

t()

@type t() :: %ExOutlines.Backend.Mock{agent_pid: pid(), call_count: non_neg_integer()}

Functions

always(response)

@spec always(response()) :: t()

Create a mock that always returns the same response.

Examples

iex> mock = ExOutlines.Backend.Mock.always({:ok, "same response"})
iex> is_struct(mock, ExOutlines.Backend.Mock)
true

always_fail(error)

@spec always_fail(term()) :: t()

Create a mock that always fails with the given error.

Examples

iex> mock = ExOutlines.Backend.Mock.always_fail(:timeout)
iex> is_struct(mock, ExOutlines.Backend.Mock)
true

call_count(mock)

@spec call_count(t()) :: non_neg_integer()

Get the number of times this mock has been called.

Examples

iex> mock = ExOutlines.Backend.Mock.new([{:ok, "response"}])
iex> ExOutlines.Backend.Mock.call_count(mock)
0

call_llm(messages, opts)

Call the mock backend.

Returns the next response in sequence. This implementation is stateless, so you need to pass the mock instance with state if using in a process.

For use with ExOutlines.generate/2, pass the mock struct in backend_opts:

ExOutlines.generate(spec,
  backend: ExOutlines.Backend.Mock,
  backend_opts: [mock: mock]
)

new(responses)

@spec new([response()]) :: t()

Create a new mock backend with pre-configured responses.

Responses are returned in order. After exhausting all responses, returns {:error, :no_more_responses}.

Examples

iex> mock = ExOutlines.Backend.Mock.new([
...>   {:ok, "response 1"},
...>   {:ok, "response 2"}
...> ])
iex> is_struct(mock, ExOutlines.Backend.Mock)
true