skip to content

In a component test, what does mounting a tree into a test host mean, and what does the root handle it returns let you do?

level: juniorimportance: must knowfreq 70%

answer

  1. no host, nothing to render into
  2. the container the test creates
  3. mounting returns a handle on a root
  4. teardown runs the destroy path

basics

~20 s

Mounting attaches a component tree to a host the test owns — usually a container the test created in a simulated document — and returns a root handle. Through it the test queries rendered output, feeds new inputs into the same root, and tears the tree down.

solid answer

~50 s

A component framework renders into a host, so a test has to supply one: a container it creates in a simulated document inside the runner, or a node on a real page in a browser engine. The mount call builds a `root` there and hands back a handle. The handle carries the container the assertions query, an entry point for pushing new inputs into that same root, and a teardown call. Keeping it matters because a mounted tree owns live things — listeners on host nodes and globals, timers, subscriptions, content rendered through a portal outside the container — and only tearing the root down runs the framework's destroy path that unwinds them. Mounting a second time into a fresh container is not an update; it is a second, unrelated tree with its own state.

go deeper

for a junior

Remember the three harness steps: create a container the test owns, mount a root into it, tear that root down at the end. Assertions query the container, and the handle is what lets you do the other two.

for a middle

Be able to say what the root owns beyond markup — listeners, timers, subscriptions, portal content — and why unwinding it must go through the framework's destroy path rather than deleting a node.

for a senior

Show you have debugged a suite where a root outlived its test: a timer still firing, a subscription still pushing, stale output found by a later query. Say how you proved which test leaked it.

for a principal

Decide whether teardown is guaranteed by the harness or left to each author to remember, and price what one escaped root costs in a suite of thousands of tests sharing a process.

## What a test host is A component framework does not draw anything on its own. It computes output and applies it to a **host**: a document in the browser, a view tree on a native platform. A test therefore has to supply that host before anything can be mounted, and two families of host are used in practice. - **A simulated document inside the test runner** — an in-process implementation of the document APIs. It starts in milliseconds, so a suite can create and throw away thousands of containers. - **A real engine** — an actual browser or platform view tree driven from the test, where the host is a real page that is really laid out and painted. In both cases the test creates its own container rather than reusing whatever node happens to be there. A container the test created is empty by construction, and that is what makes one test's output distinguishable from another's. ## What the mount call hands back Mounting is not a fire-and-forget call. The framework creates a **root** — its own record of the tree it owns inside that container — and the test keeps a handle on it. | The handle carries | What the test needs it for | | --- | --- | | the container | querying the rendered output the assertions run against | | an update entry point | feeding new inputs into the **same** root instead of mounting a second one | | a teardown call | unwinding the tree through the framework's own destroy path | | in some frameworks, a settle primitive | applying queued work so an assertion sees the new output | The second row is the one most often missed. Mounting the same component again into a fresh container updates nothing: it builds a second, unrelated tree with its own state, and the assertion then runs against a component that never saw the first set of inputs. Updating means handing new inputs to the root that already exists, so the existing instances survive and the framework reconciles rather than starting over. ## Why teardown has to go through the framework A mounted tree is not just markup. Over its life it registers things that live outside the container: - event listeners on host nodes, and on globals such as the window or the document; - timers and intervals, animation-frame callbacks, observers; - subscriptions to stores, streams, sockets and event buses; - content rendered through a portal into a node **outside** the container; - entries in module-level caches and singletons the tree touched. Deleting the container node removes markup and nothing else. The framework still holds its root, the components' teardown callbacks never run, and everything in that list stays alive. In a runner that executes many test files in one process, that is exactly how a suite starts failing in ways that depend on order: a timer from an earlier test fires into a later one, a subscription pushes into a tree nobody can see, or portal output is still in the document when the next test queries it. Calling the root's teardown runs the destroy path instead: the framework walks the tree it owns, runs each component's cleanup, and releases it. That is the only mechanism that unwinds what the tree registered, because only the framework knows what was registered. ## The shape of a mount-based test 1. Create the container in the host the test owns. 2. Mount the root, keeping the handle. 3. Drive the tree — new inputs through the root, or an interaction. 4. Settle: a write only queues work, so run the framework's settle step before asserting. 5. Assert on what the container now holds. 6. Tear the root down. Steps 1, 2 and 6 are the harness; steps 3 to 5 are the test. ## What mounting alone does not give you - **Applied updates.** The first render is usually in place by the time mount returns, but a write made *afterwards* is queued; without the settle step the container still holds the previous output. - **Geometry.** A host with no layout engine answers size and position queries with stubbed values, so nothing measured there is real. - **Full isolation.** Mounting into your own container prevents one class of bleed between tests; the listeners, timers and subscriptions above are the other class, and only teardown handles those. When a component test behaves strangely, printing what the container actually holds at the moment of the failing assertion settles most of it quickly. The surprise is usually one of three things: the tree never mounted where you thought, the update was never settled, or an earlier test's root is still running.

  • What can outlive a test whose root is never torn down?
    Everything the tree registered and the framework would unwind on destroy: listeners on host nodes and on globals, timers and intervals, observers, subscriptions to stores or streams, and content rendered through a portal into a node outside the container. In a runner that reuses one process, those keep firing into later tests.
  • Why is removing the container node not a substitute for tearing the root down?
    Removing the node detaches markup but never runs the framework's destroy path, so each component's cleanup is skipped and everything it registered stays alive. The framework also still holds its root, so it can keep scheduling work against nodes nobody can see.
  • Why does mounting the same component a second time not count as updating it?
    A second mount creates a second root with fresh instances and fresh state, so nothing carries over from the first tree and no reconciliation happens. To exercise an input change you push new inputs through the existing root's update entry point, which keeps the instances alive and lets the framework diff.

saying these in an interview costs you the question

  • Thinks a component renders with no host container at all
  • Assumes a write made after mount is visible without settling
  • Removes the container node by hand instead of tearing the root down
  • Mounts a second time to simulate an input change
  • Assumes the framework tears trees down when a test file ends