skills/mocking-network-and-time/SKILL.md
Decides what to fake and stubs it correctly: network interception with Playwright route or HAR replay, MSW handlers, fake clocks, and fixed timezones. Use when a test depends on a third party, when a date-sensitive test breaks overnight, when a suite is slow because it calls real services, or when a mocked test stays green while production is broken.
npx skillsauth add jaktestowac/awesome-copilot-for-testers mocking-network-and-timeInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use this skill when a test is unreliable, slow, or unrepeatable because it reaches something the test cannot control: someone else's API, the wall clock, the machine's timezone, or a payment sandbox that rate-limits on Fridays.
Mocking buys determinism and pays for it in fidelity. Every mock is a claim about how the real dependency behaves, and that claim rots silently. The skill is not "how do I stub this", it is "what should stay real, what should be faked, and how do I find out when a fake has drifted from the thing it imitates".
route, and a real test environmentBefore choosing a tool, say what exactly is uncontrolled. One of:
A test can suffer more than one. Fix them separately; a single "make it deterministic" change that touches all four is unreviewable.
Work through ./resources/when-to-mock.md. It maps test level against dependency type and gives the default for each cell.
The two defaults worth stating up front:
If the answer is "mock our own API in an end-to-end test", the test has stopped being end-to-end. Say so and either accept it as an integration test or keep the backend real.
| Layer | Tool | Use when |
| --- | --- | --- |
| Browser network | Playwright page.route / context.route | E2E, stubbing a third party or forcing an error response |
| Recorded traffic | Playwright HAR replay | E2E against a large read-only API surface you do not want to hand-write |
| Application fetch layer | MSW (setupServer / setupWorker) | Component and integration tests, shared handlers across runners |
| Module boundary | Runner mocks (vi.mock, jest.mock) | Unit tests, and only when the seam is your own module |
| Clock | Playwright clock, vi.useFakeTimers | Anything time-dependent |
| Process env | TZ, LANG, seeded random | Timezone, locale, and ID determinism |
Recipes for each are in ./resources/playwright-route-recipes.md, ./resources/msw-recipes.md, and ./resources/clock-and-timezone.md.
Prefer the highest layer that solves the problem. Mocking at the module boundary to fix a network problem couples the test to your import graph and survives no refactor.
Every stub carries four things:
onUnhandledRequest: 'error' in MSW, or an explicit catch-all route that fails the test in Playwright. Default to strict.When time matters:
clock.setFixedTime / vi.setSystemTime) to a date with no special properties, and one that is not near a DST boundary unless DST is the thing under testTZ, never rely on the CI agent's default./resources/clock-and-timezone.md has the per-runner spellings and the DST and leap-day cases worth a deliberate test.
A mock without a drift guard becomes false documentation. Pick at least one:
testing-api-contracts.Record which guard applies. "None" is an acceptable answer only for a dependency that is genuinely frozen, and it still gets written down.
Close with a short note next to the stub or in the test README:
Use ./resources/mocking-decision-record.md.
vi.mock on a module to solve what is actually a network problem./resources/when-to-mock.md - decision table by test level and dependency type, with the fidelity cost of each choice./resources/playwright-route-recipes.md - route, fulfill, abort, request modification, and HAR record and replay./resources/msw-recipes.md - node and browser setup, handler patterns, strict unhandled-request config, per-test overrides./resources/clock-and-timezone.md - fake clocks, fixed timezone and locale, DST and leap-day cases, per-runner spellings./resources/mocking-decision-record.md - short template for recording the fidelity trade and the drift guardtesting-api-contracts - when the mock needs a drift guard against the real specificationui-playwright-test-developer (planned) - when the stub is part of a wider browser test being written or refactoredapi-playwright-test-developer - when the API side of the flow is under constructionwriting-unit-tests - when the question is about test doubles at the module boundary rather than the networkstabilizing-flaky-tests (planned) - when nondeterminism remains after the network and clock are controlledunslop-tests - when the suite is mock-heavy and may be proving nothingThis skill is complete when:
testing
Tests the customization assets themselves - skills, prompts, custom agents, instructions - the way a product is tested: activation cases that check an asset fires when it should and stays quiet when it should not, output-contract cases, safety cases, collision cases between assets competing for the same trigger, a weighted rubric scored blind, and a baseline-versus-candidate gate before an edit ships. Use when a skill is edited and nobody knows whether behaviour changed, when two skills fight over the same request, when a description is being tuned for discoverability, when a collection has grown past manual spot-checking, or when the request mentions skill evals, prompt regression, or "does this skill actually work".
development
Shapes QA output for the person who has to act on it: result and blocker in the first two lines, one decision per report, findings ordered by what they cost, the long artifact in a file and the decisions in the message, and magnitude stated in units the reader can count. Use when a report is accurate but nobody acts on it, when a finding set is too long to read under time pressure, when the same findings must be retold for a developer, a release manager, and an on-call engineer, or when the request mentions "too long", "make this readable", "just tell me what to do", "so what", or "summarize this for stakeholders". Pairs with unslop-answers, which makes the same report honest.
testing
Verifies that the lines and branches a change actually touched are executed by tests, using LCOV or Cobertura diff coverage instead of whole-repo percentages, and escalates uncovered high-risk changes into a blocking finding. Use when a pull request needs a coverage gate that unrelated tests cannot satisfy, when total coverage looks healthy but the diff is untested, when wiring diff coverage into CI, or when someone claims a change is covered because the suite is green.
development
Cuts AI tells from test code: tests that pass without proving anything, tautological assertions, mock-only tests, hardcoded waits, coverage theater, vague names, swallowed errors, retries used as fixes. Use whenever test code is written, changed, or reviewed, including tests produced as a side effect of a feature task, and when the request mentions "review these tests", "are these tests any good", "this test always passes", "this suite is flaky", or "clean up these tests". Must always apply to test code.