Skip to main content
Related: Observability, DX, Client, Troubleshooting Test-only helpers to run the search layer offline (no I/O by default) and write ergonomic assertions against unified events and compiled params.

Quick start

The engine automatically uses an offline client in test mode (Rails test environment or RACK_ENV=test). For programmable responses, enable the stub client:
  • Queue responses and inspect captured calls:
  • Programmable responses via blocks or exceptions:
  • Use the SearchEngine.client helper to access the configured client:

Event assertions

Unified events are emitted via ActiveSupport::Notifications. Capture them for a block and assert.
  • RSpec matcher:
  • Minitest helpers:
  • Params helpers in tests:
See also: Relation#to_params_json, Relation#to_curl, and Relation#dry_run!.

Test mode and offline client

The engine automatically enables test mode when running in Rails test environment or when RACK_ENV=test is set. In test mode, SearchEngine.client returns a no-op SearchEngine::Test::OfflineClient that avoids network I/O and returns safe empty responses.

Environment overrides

You can control test mode via environment variables:
  • SEARCH_ENGINE_TEST_MODE=1 or SEARCH_ENGINE_TEST_MODE=0 (explicit override)
  • SEARCH_ENGINE_OFFLINE=1 or SEARCH_ENGINE_OFFLINE=0 (legacy alias)
When SearchEngine.config.client is explicitly set (e.g., StubClient), it always takes precedence over automatic offline mode.

OfflineClient behavior

SearchEngine::Test::OfflineClient implements all client methods but performs no network I/O:
  • search returns empty results (found: 0)
  • multi_search returns empty results array
  • import_documents returns success JSONL
  • All other operations return safe empty responses

Offline strategy & safety

  • Captured bodies and event payloads are redacted via the central helper.
  • No API keys, raw filter literals, or PII are stored; long strings are truncated.
  • A redacted? marker is present on captured request entries.

Parallel test safety

  • Internals are protected by a lightweight mutex.
  • Use stub.reset! between examples if needed.
Backlinks: Observability, DX, CLI, Client