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:
| Layer | Type | Responsibility |
|---|---|---|
| Adapter | XceptoAdapter | User-facing entry point; exposes domain methods that return builders |
| Builder | AbstractStateBuilderIdentity<T> / custom | Accumulates fluent configuration; registers and replaces a lazy step |
| State | XceptoState | Executes 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 withTransitionBuilder, hasinitialize/terminatelifecycle, exposes domain methods*AdapterBuilder— a configuration builder that collects dependencies and callsTransitionBuilder.registerAdapter()inbuild()/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;onEntervsevaluateConditionsForTransition - Fluent Builder — extend
AbstractStateBuilderIdentity<T>; parameterized, replaceable steps