Public API for starting and controlling dummy Redis servers for integration tests.
The main entry points are:
start_link/1– start a new Redis-compatible dummy serverchild_spec/1– embed the server directly in your supervision treestub/2andstub/3– define stub rules for commandsexpect/3– define expectation rules for commandscalls/1– fetch the history of executed commandsreset!/1– reset server state between testsport/1– get the TCP port the server is listening onaddress/1–{host, port}tuple for wiring external clients (host is"127.0.0.1"unless you only need the port)stop/1– stop the server
See the project README for more detailed examples.
Summary
Types
A recorded command call, suitable for assertions in tests.
A Redis command name, case-insensitive.
Matcher used to select which commands should be affected by a stub/expectation.
Response specification used by stubs and expectations.
A server reference; can be a PID or a registered name.
Functions
Returns {host, port} for pointing external systems (for example ejabberd)
at this FauxRedis instance.
Returns the list of all command calls observed by a server.
Returns a child_spec/1 suitable for embedding the server under a supervisor.
Adds an expectation rule.
Returns the TCP port the server is currently listening on.
Resets the server state
Starts a new dummy Redis server.
Stops the server gracefully.
Adds a stub rule using an options keyword list.
Convenience stub form: stub(server, matcher, response_spec).
Types
@type call_record() :: %{ conn_id: non_neg_integer(), name: String.t(), args: [binary()], db: non_neg_integer(), timestamp: integer(), rule_id: reference() | nil, action: term() }
A recorded command call, suitable for assertions in tests.
A Redis command name, case-insensitive.
@type matcher() :: command_name() | {:command, command_name(), [binary() | :any | Regex.t()]} | {:fn, (FauxRedis.Command.t() -> boolean())}
Matcher used to select which commands should be affected by a stub/expectation.
- a simple command name (string or atom), e.g.
"GET"or:get {:command, name, args_pattern}whereargs_patternis a list of:- exact binary values
:anywildcard~r/.../regular expressions
{:fn, fun}– predicate functionfun.(command) :: boolean
@type response_spec() :: term() | {:delay, non_neg_integer(), response_spec()} | :timeout | :no_reply | :close | {:close, response_spec()} | {:protocol_error, iodata()} | {:partial, [iodata()]} | {:fun, (FauxRedis.Command.t() -> response_spec())} | [response_spec()]
Response specification used by stubs and expectations.
Supported forms:
- any plain value that can be encoded as RESP:
- binary (bulk string)
- integer
nil(null bulk string)- list (arrays)
{:error, message}(error reply):ok(simple string "OK")
{:delay, ms, inner}– delay sendinginnerbymsmilliseconds:timeoutor:no_reply– do not send any reply:close– immediately close the TCP connection{:close, inner}– sendinnerthen close the connection{:protocol_error, binary}– send raw invalid bytes{:partial, [iodata()]}– send raw chunks as-is, one by one{:fun, fun}– callbackfun.(command) :: response_spec- a non-empty list of response specs – used sequentially per matcher
@type server() :: GenServer.server()
A server reference; can be a PID or a registered name.
Functions
@spec address(server()) :: {String.t(), non_neg_integer()}
Returns {host, port} for pointing external systems (for example ejabberd)
at this FauxRedis instance.
By default the server binds to 127.0.0.1, so the host is always
"127.0.0.1" unless you override the :ip option when starting the
server and manage host/port mapping yourself (e.g. via Docker).
@spec calls(server()) :: [call_record()]
Returns the list of all command calls observed by a server.
The records are ordered by time and include information that is useful for assertions in tests (connection id, DB index, matched rule id, etc.).
@spec child_spec(Keyword.t()) :: Supervisor.child_spec()
Returns a child_spec/1 suitable for embedding the server under a supervisor.
@spec expect(server(), matcher(), response_spec()) :: {:ok, reference()}
Adds an expectation rule.
Semantics are the same as for stub/3, but expectations are intended to be
asserted via calls/1 in your tests. The engine will keep track of how many
times each expectation was used.
@spec port(server()) :: non_neg_integer()
Returns the TCP port the server is currently listening on.
@spec reset!(server()) :: :ok
Resets the server state:
- clears all keys and data structures
- clears TTLs
- clears all mock rules and expectations
- clears call history
@spec start_link(Keyword.t()) :: GenServer.on_start()
Starts a new dummy Redis server.
Options:
:port– TCP port to listen on (defaults to0, meaning a random free port):mode– one of::mock_first(default) – try mock rules first, fall back to built-in semantics:stateful_only– ignore mock rules, act as a simple in-memory Redis:mock_only– only apply mock rules, unknown commands are errors
:name– optional registered name (viaRegistry.FauxRedis.ServerRegistry):require_auth?– whether connections must AUTH before using the server (default:false):password– expected password for AUTH (only meaningful when:require_auth?istrue)
@spec stop(server()) :: :ok
Stops the server gracefully.
Adds a stub rule using an options keyword list.
This is the most flexible form and supports all fields of FauxRedis.MockRule.
Basic usage:
{:ok, rule_id} =
FauxRedis.stub(server,
matcher: :get,
respond: "bar"
)
@spec stub(server(), matcher(), response_spec()) :: {:ok, reference()}
Convenience stub form: stub(server, matcher, response_spec).
Examples:
# Always return "bar" for any GET
FauxRedis.stub(server, :get, "bar")
# Sequential responses for GET
FauxRedis.stub(server, :get, ["one", "two", nil])