Stateless stub for DoubleDown.Repo.
Write operations (insert, update, delete) apply changeset
changes and return {:ok, struct} but store nothing. Read
operations go through an optional fallback function, or raise a
clear error.
Implements DoubleDown.Contract.Dispatch.StubHandler, so it can
be used by module name with Double.stub:
Usage with Double.stub
# Writes only — reads will raise with a helpful message:
DoubleDown.Double.stub(DoubleDown.Repo, DoubleDown.Repo.Stub)
# With fallback for specific reads:
DoubleDown.Double.stub(DoubleDown.Repo, DoubleDown.Repo.Stub,
fn
:get, [User, 1] -> %User{id: 1, name: "Alice"}
:all, [User] -> [%User{id: 1, name: "Alice"}]
:exists?, [User] -> true
end
)
# Layer expects on top for failure simulation:
DoubleDown.Repo
|> DoubleDown.Double.stub(DoubleDown.Repo.Stub)
|> DoubleDown.Double.expect(:insert, fn [changeset] ->
{:error, Ecto.Changeset.add_error(changeset, :email, "taken")}
end)When to use Repo.Stub
Use Repo.Stub when your test only needs fire-and-forget writes
and a few canned read responses. It's the lightest-weight option —
no state to reason about.
For read-after-write consistency, use Repo.InMemory (closed-world,
recommended) or Repo.OpenInMemory (open-world, fallback-based).
| Fake | State | Reads |
|---|---|---|
Repo.Stub | None | Fallback function or raise |
Repo.InMemory | Complete store | Authoritative for bare schemas |
Repo.OpenInMemory | Partial store | PK lookup in state, fallback for rest |
Summary
Functions
Create a new Test handler function.
Functions
Create a new Test handler function.
Returns a 2-arity function (operation, args) -> result suitable for
use with DoubleDown.Double.stub/2 or DoubleDown.Testing.set_fn_handler/2.
Arguments
fallback_fn— an optional 2-arity function(operation, args) -> resultthat handles read operations. If the function raisesFunctionClauseError(no matching clause), dispatch falls through to an error. If omitted ornil, all reads raise immediately.opts— keyword options (reserved for future use).
Examples
# Writes only — via module name (StubHandler)
DoubleDown.Double.stub(DoubleDown.Repo, DoubleDown.Repo.Stub)
# With fallback for specific reads
DoubleDown.Double.stub(DoubleDown.Repo, DoubleDown.Repo.Stub,
fn
:get, [User, 1] -> %User{id: 1, name: "Alice"}
:all, [User] -> [%User{id: 1, name: "Alice"}]
:exists?, [User] -> true
end
)Legacy keyword-only form (still supported)
DoubleDown.Repo.Stub.new(fallback_fn: fn :get, [User, 1] -> %User{} end)