🔑 Why MockChain Is a Chain
🔑 Why MockChain Is a Chain
When testing asynchronous methods, you often want to control behavior without rewriting the method logic. MockChain allows you to inject and observe behavior at any point in a promise chain, not just at the start.
🧩 Two Ends of the Chain
Consider a typical async method:
function fetchData(url, opts, autoStart = true) {
return MockChain.fromResponse(url, opts, autoStart)
.then(res => res.json())
.then(obj => obj.ok);
}
There are three promises involved:
- Root node (
root) — the initial wrapped promise (e.g.,fetch()) resolving to a Response object. - Mid node — the in-between promise resolving to the JSON object.
- Leaf node (
end) — the last node resolving to a Boolean flag.
In tests, you usually mock the root to trigger the end manually:
const chain = fetchData(undefined, undefined, false); // don’t await — get the mockable chain
chain.root.mock(new Response(JSON.stringify({ ok: true }))); // inject mock Response
const flag = await chain; // await leaf node resolution
console.log(flag); // -> true
🃏 Walking the Chain
Each MockChain node tracks both its parent node. This lets you navigate the chain and mock any intermediate step:
let end = fetchData(undefined, undefined, false);
const mid = end.parent; // walk one step up
const root = mid.parent; // go to the root node
mid.mock({ ok: false }); // mock mid-level transformation
const flag = await end; // observe downstream effect
console.log(flag); // -> false
By exposing .parent and .root, MockChain allows testing at different depths of your async flow — verifying transformations, simulating partial failures, or injecting data exactly where needed.
🧠 Why This Matters
Traditional Promise chains are opaque — each .then() hides its intermediate state. MockChain keeps the structure visible and testable:
- Mock upstream to control inputs.
- Inspect or mock midstream to verify transformations.
- Observe downstream to confirm outcomes.
This lets you navigate the logical flow of async code — injecting or inspecting results at any depth with full determinism.
Comments
Post a Comment