As the owner of a large component-test suite, how do you decide how much of the application's real provider stack the default mount wires?
answer
- the default mount is a policy
- too thin drifts, too thick blurs
- real if in-process and deterministic
- layered helpers, not one with flags
- escaped defects move the default
basics
~10 sPer collaborator, by cost and evidence: run in-process deterministic ones for real, stand in for anything crossing a boundary or a clock. Publish the default, make deviations explicit, revise it when defects escape.
solid answer
~50 sThe default mount is a policy, not a utility. Wire too little and every test hand-builds context, fidelity varies file to file, and nobody can say what the suite covers. Wire too much and each test mounts most of the application: failures stop localising, runs slow, and a test named after one component fails because an unrelated provider changed. I set the default per class of collaborator. Anything in-process and deterministic runs for real — external state, a router over an in-memory history, formatting, permission evaluation — because that is behaviour I want covered and it is cheap. Anything crossing a boundary or depending on real time gets a stand-in at a consistent seam. Everything else is an explicit option, so a lowered-fidelity choice appears in the test that made it. Then I watch which defects escape and move the default when the evidence repeats.
go deeper
Use the standard mount your team provides and pass the case's own values. Noticing when it seems to wire too much or too little is the useful contribution here.
Be able to argue why in-process deterministic collaborators run for real while boundary-crossing ones get stand-ins, and what each choice costs a test's run time.
Show you keep the helper in step with the application's composition and that lowered fidelity is explicit at the call site so coverage gaps are countable.
Own it as policy: a per-collaborator default with a written rationale, layered entry points, a tracked setup-cost budget, and revision driven by escaped-defect patterns.
## The default mount is a policy decision In a suite of thousands of component tests, one helper decides what almost every test's environment is. That makes it the highest-leverage piece of test infrastructure in the codebase and the one most often written in an afternoon and never revisited. Treat it as a policy with an owner, a stated rationale, and a review process. ## The two failure modes **Too thin.** The helper wraps almost nothing, so each test assembles its own context. Consequences: duplicated wiring that drifts from the application's composition, inconsistent fidelity nobody can audit, and a long tail of tests that pass because their stand-ins were generous. **Too thick.** The helper mounts effectively the whole application above every component. Consequences: slow runs; a failure in a shared provider fails hundreds of unrelated tests; new engineers cannot tell which parts of a passing test were exercised; and the suite quietly becomes a slow integration suite with unit-test names. Neither is a knob you set once — they are the ends of an axis you keep choosing a point on. ## A per-collaborator default | Collaborator | Default | Why | |---|---|---| | External state store | Real, fresh per test, seeded | In-process and deterministic; its update and selection behaviour is worth covering | | Router | Real, over an in-memory history | Matching, redirects and links are behaviour, not plumbing, and cost nothing to run | | Locale, formatting, theme | Real, with an explicit default | Cheap, and a stand-in would hide formatting defects that users see | | Permission or session evaluation | Real logic, with the principal supplied per test | Substituting the decision is how permission bugs escape | | Data layer / transport | Stand-in at one consistent seam | Crosses a boundary; real calls are slow, flaky and shared | | Clock, randomness, identifiers | Controlled | Non-determinism turns unrelated tests red | | Persistence, workers, host-level services | Stand-in unless the test is about them | Environment-dependent, and a leak across tests is hard to diagnose | The pattern is not "fake the hard things". It is: **run for real whatever is in-process, deterministic, and part of the behaviour you claim to cover; stand in for whatever crosses a boundary or a clock.** ## Make the helper layered, not monolithic 1. A **minimal mount** that wraps nothing but the bare essentials, for presentational components — cheap, and it proves a component does not secretly need ambient context. 2. A **standard mount** implementing the default policy above, which most tests use. 3. **Options on the standard mount** for the case-specific values: location, seeded state, warm cache entries, the acting principal, and named collaborator overrides. 4. A small number of **full-stack mounts** for flow-level tests that deliberately want the whole composition. Layering matters because a single helper forced to serve every case grows flags until nobody can predict what a call does. ## Governance, not just design - **One owner and a written rationale.** A short document saying what the default wires and why turns "the helper does something weird" into an argument you can have. - **Deviations are explicit and greppable.** If a test lowers fidelity, it says so at the call site. You can then count how many tests substitute a given collaborator — a number that tells you where coverage is thin. - **Keep it in step with the application.** When the app adds a provider, the helper changes in the same review; otherwise every test mounts a stale shape. - **Budget the cost.** Track the suite's wall-clock time and the fraction spent in setup. A default stack that doubles every test's setup cost is a real spend, and worth it only for evidence it buys. - **Let escaped defects move the policy.** Every production defect that a component test structurally could not have caught is evidence about the default: was the missing piece a provider that was faked, a seam substituted too high, or a class of behaviour that belongs in a different kind of test entirely? Change the default when the pattern repeats, not on one incident. ## The honest limit No default stack makes component tests into evidence about the deployed system: the substituted boundary is still substituted, and the host is simulated. The policy's job is to make the fidelity *uniform and visible* so the rest of the portfolio can be planned around it. Say that plainly — the failure mode of this question is a candidate who promises that a rich enough wrapper removes the need for tests at other levels.
- What signal tells you the default stack is too thick?Failures stop localising: a change to one shared provider reddens hundreds of tests across unrelated components, and setup dominates run time. A second signal is social — engineers cannot say what a passing test actually exercised, and start writing their own narrower mounts beside the helper.
- How do you make the suite's fidelity auditable rather than a matter of folklore?Make every deviation from the default explicit at the call site and countable by search, keep the default's rationale written down next to the helper, and review helper changes with the same care as application code. You can then answer, with numbers, which collaborators most tests substitute and where coverage is therefore thin.
- How would you raise fidelity in a suite that substitutes too much, without stalling delivery?Change the default for one collaborator class at a time, starting where escaped defects point. Let existing tests opt back into the old stand-in explicitly, so the migration is visible and countable rather than a mass rewrite, then burn that list down as teams touch the files. Measure run time at each step so the cost stays deliberate.
- Why keep a minimal mount alongside the standard one?It proves a component works without ambient context, which is worth knowing for a shared presentational component, and it keeps cheap tests cheap. It also acts as a design check: if a component that should be presentational fails to mount minimally, it is reaching for context it should receive as inputs.
saying these in an interview costs you the question
- Treats the shared mount helper as a utility nobody needs to own
- Substitutes permission or formatting logic by default, hiding user-visible defects
- Wires the entire application above every component and calls it realism
- Grows one helper with a dozen flags instead of layered entry points
- Claims a rich enough test wrapper removes the need for higher-level tests
- Changes the default policy after a single incident with no pattern behind it