0003-relocate-testutil-to-factory
ADR 0003: Relocate adapter test helpers to internal/adapter/factory
Status: Proposed
Date: 2025-09-11
Author: (please fill: repo owner)
Context
The repository contains small test helper factories under internal/adapter/testutil that produce seeded adapters and RefreshFunc fixtures for unit and handler tests. During refactors these helpers initially returned any to avoid import cycles; later changes made them return adapter.Adapter successfully. However, placing these helpers under internal/adapter/testutil creates a package dependency graph that can be confusing and risks accidental import cycles when other packages want to reuse factories.
Decision
Move the test helper factories into a new package internal/adapter/factory and treat that package as the canonical location for programmatic adapter construction used by tests and examples. The factory package will:
- Depend only on
internal/adapter(the interface),internal/adapter/memory(provider), andinternal/modelas needed. - Export typed factory functions that return
adapter.Adapter(noany), e.g.NewSeededAdapter() (adapter.Adapter, error)andNewAdapterFromData(...) (adapter.Adapter, error). - Avoid importing any packages that themselves import test-only helper packages to keep the dependency graph acyclic.
Rationale
- Clearer package responsibility:
factoryis explicitly a construction helper and not a test package. - Eliminates historical
anyreturns and the need for tests to type-assert. - Reduces risk of import cycles and makes package dependencies explicit.
- Easier discovery: other packages and integration tests can import
internal/adapter/factorywhen they need seeded adapters.
Consequences
- Minor API change for tests: imports change from
internal/adapter/testutiltointernal/adapter/factory. - A small migration effort is required to update test imports and README/documentation.
- The
testutilpackage may be removed after migration or kept as a thin compatibility shim for a release cycle.
Alternatives considered
-
Keep
testutilbut rename itfactoryin-place.- Pros: minimal filesystem churn.
- Cons: still ambiguous —
testutilname signals test-only code; a neutralfactoryname clarifies broader applicability.
-
Keep helpers where they are and accept
anyreturn types.- Pros: least immediate work.
- Cons: retains type-asserts and reduces API clarity; risks future import-cycle regressions.
-
Move factories into a separate top-level
internal/testhelperspackage.- Pros: makes it clear they are test helpers.
- Cons: increases surface area and may encourage non-adapters to depend on test helpers.
Migration plan
- Add new package
internal/adapter/factorywith equivalent functions implemented in the existingtestutilcode, returningadapter.Adapter. - Update existing tests to import
internal/adapter/factoryinstead ofinternal/adapter/testutiland remove type-assertions. - Run
go test ./...and fix any remaining import or build issues. - Optionally leave a lightweight
internal/adapter/testutilthat re-exportsfactoryfunctions (deprecated) for one release to ease migration, then delete it.
Rollback
If the migration introduces unexpected build or import-cycle issues, revert to the previous commit and implement a compatibility shim (step 4 above) to provide the old APIs while diagnosing cycles.
Open questions
- Author/Approver: please fill in the ADR metadata (Author and Approver) and confirm the preferred migration window (immediate vs. staged compatibility shim).
- Naming: confirm
factoryvsbuildervsconstructas the package name.