Skip to main content

Why Build a Custom Adapter?

The built-in adapters (REST, SSR, RabbitMQ) cover the most common integration patterns. Build a custom adapter when:

  • You need to interact with a technology not covered by a built-in adapter (gRPC, WebSockets, a domain-specific client, an in-process service)
  • You want to create a domain-specific test DSL — readable fluent builder chains like users.User(email).WithRole(Role.Admin).ShouldBeVisible() that hide HTTP mechanics behind domain vocabulary
  • You are building a reusable test library for other teams consuming your platform

Architecture

A custom adapter consists of three layers:

LayerTypeResponsibility
AdapterXceptoAdapterUser-facing entry point; exposes domain methods that return builders
BuilderAbstractStateBuilderIdentity<T> / customAccumulates fluent configuration; registers and replaces a lazy step
StateXceptoStateExecutes the action or condition when the machine reaches it

For HTTP-based custom adapters, extend AbstractHttpStateBuilderIdentity<T> from xceptoj-http / Xcepto to inherit the full shared fluent API (assertions, query arguments, retry control, URL building) and AbstractHttpState for the execution model.

Adapter vs adapter builder

There are two distinct concepts:

  • XceptoAdapter — the runtime adapter; registered with TransitionBuilder, has initialize/terminate lifecycle, exposes domain methods
  • *AdapterBuilder — a configuration builder that collects dependencies and calls TransitionBuilder.registerAdapter() in build() / Build()

This separation keeps test code clean: the adapter builder handles wiring, the adapter exposes the test DSL.

Pages in this section

  • Custom Adapter — extend XceptoAdapter; lifecycle, addStep, domain methods
  • Custom State — extend XceptoState; onEnter vs evaluateConditionsForTransition
  • Fluent Builder — extend AbstractStateBuilderIdentity<T>; parameterized, replaceable steps