Skip to content

Document deterministic timing test patterns and Clock-trait reuse strategy #193

@coderabbitai

Description

@coderabbitai

Background

PR #175 introduced a Clock trait (SystemClock / FixedClock) into src/tools/builder/core/wrapper.rs to enable one deterministic timing assertion in wrapper_tests.rs. The trait adds measurable production complexity — an Arc<dyn Clock> field, a trait definition, a SystemClock impl, and a test-only constructor — without a stated reuse strategy or an explanation of when this pattern should be preferred over alternatives.

Separately, issue #113 tracks replacing hand-rolled stubs with mockall-generated mocks. These two pieces of work share the same root concern: the project lacks a single, authoritative source of truth for how time-dependent and other injectable dependencies should be tested deterministically.

Required work

  1. Testing-strategy documentation — Update docs/testing-strategy.md (and/or docs/reliable-testing-in-rust-via-dependency-injection.md / docs/testing-abstractions.md) to include a dedicated section on deterministic timing tests. The section must:

    • State the rule: wall-clock calls (Instant::now, Utc::now, SystemTime::now) must never appear in test assertions.
    • Document the approved pattern: define a Clock trait (or equivalent) with a production SystemClock impl and an injectable FixedClock test double.
    • Set out where shared clock/time abstractions should live (e.g. a crate::clock module) to avoid re-implementing the same trait per feature module.
    • Cover repeatability requirements: test doubles must be Clone, Send, and Sync; snapshot assertions over time-containing output must use the injected fixed value.
  2. Mock injection guidance — Add or extend documentation to cover:

    • When to use mockall-generated mocks vs hand-written fakes vs FixedClock-style test doubles.
    • The approved mockall / mockable usage patterns for async traits, including the #[automock] and #[cfg_attr(test, automock)] forms.
    • A worked example (ideally a doctest or inline code block in the guide) showing a Clock-injected struct under test.
  3. Shared clock module — Evaluate extracting the Clock trait and SystemClock / FixedClock impls into a shared location (e.g. src/clock.rs or src/testing/clock.rs) so the pattern is reusable across crates without per-module duplication.

Acceptance criteria

  • docs/testing-strategy.md (or a linked testing-abstractions document) contains the deterministic-timing rule and the approved pattern with a code example.
  • The mock-injection section documents mockall usage and the criteria for choosing between mockall and hand-written doubles.
  • A shared clock module exists (or a documented rationale for not extracting one is present in the ADR log).
  • cargo nextest run --workspace --features test-helpers --profile default passes.

References

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions