[{"data":1,"prerenderedAt":3762},["ShallowReactive",2],{"page-\u002Fjs\u002F25-testing":3},{"id":4,"title":5,"body":6,"description":116,"extension":3756,"meta":3757,"navigation":35,"path":3758,"seo":3759,"stem":3760,"__hash__":3761},"content\u002Fjs\u002F25-testing.md","25 — Testing",{"type":7,"value":8,"toc":3727},"minimark",[9,13,77,323,389,539,732,975,1138,1333,1470,1521,1786,2062,2376,2613,2900,3107,3158,3383,3430,3723],[10,11,5],"h1",{"id":12},"_25-testing",[14,15,17,22,56],"question-wrapper",{"language":16},"javascript",[18,19,21],"h3",{"id":20},"q1-what-best-characterizes-the-difference-between-unit-integration-and-end-to-end-e2e-tests","Q1. What best characterizes the difference between unit, integration, and end-to-end (E2E) tests?",[23,24,27,38,44,50],"ul",{"className":25},[26],"contains-task-list",[28,29,32,37],"li",{"className":30},[31],"task-list-item",[33,34],"input",{"disabled":35,"type":36},true,"checkbox"," Unit tests exercise the whole app through the UI, so they give the highest confidence but run slowest",[28,39,41,43],{"className":40},[31],[33,42],{"disabled":35,"type":36}," Unit tests verify a single function\u002Fmodule in isolation and run fastest; integration tests verify multiple units working together; end-to-end tests drive the real app like a user and give the highest confidence but are slowest and most brittle",[28,45,47,49],{"className":46},[31],[33,48],{"disabled":35,"type":36}," Integration tests are always slower than end-to-end tests, because they spin up a full browser",[28,51,53,55],{"className":52},[31],[33,54],{"disabled":35,"type":36}," End-to-end tests replace the need for unit tests once a project has enough of them",[57,58,59,63,71],"details",{},[60,61,62],"summary",{},"Show Answer",[64,65,66,70],"p",{},[67,68,69],"strong",{},"Answer:"," B — Unit tests verify a single function\u002Fmodule in isolation and run fastest; integration tests verify multiple units working together; end-to-end tests drive the real app like a user and give the highest confidence but are slowest and most brittle",[64,72,73,76],{},[67,74,75],{},"Explanation:"," This is the classic testing pyramid tradeoff: isolation and speed decrease as confidence increases. Unit tests are cheap and fast because they touch no real collaborators; E2E tests are expensive and slow because they exercise the real browser, network, and database, but they catch integration bugs unit tests structurally cannot see. Option A reverses the definitions — unit tests never touch the UI. Option C gets the ordering backwards; E2E is typically the slowest tier because it pays for a real browser and real I\u002FO, with integration tests in between. Option D is wrong because the pyramid recommends many unit tests, fewer integration tests, and the fewest E2E tests as complements, not replacements — E2E tests alone are too slow and flaky to run on every change.",[14,78,79,108,265,305],{"language":16},[18,80,82,83,87,88,91,92,95,96,99,100,103,104,107],{"id":81},"q2-you-have-processordercart-paymentgateway-which-totals-a-cart-and-charges-a-payment-gateway-a-test-constructs-an-in-memory-inmemorycart-and-a-fakepaymentgateway-calls-processorder-and-asserts-the-resulting-orders-status-is-paid-what-kind-of-test-is-this","Q2. You have ",[84,85,86],"code",{},"processOrder(cart, paymentGateway)",", which totals a cart and charges a payment gateway. A test constructs an in-memory ",[84,89,90],{},"InMemoryCart"," and a ",[84,93,94],{},"FakePaymentGateway",", calls ",[84,97,98],{},"processOrder",", and asserts the resulting order's ",[84,101,102],{},"status"," is ",[84,105,106],{},"\"paid\"",". What kind of test is this?",[109,110,111],"code-wrapper",{"language":16},[112,113,117],"pre",{"className":114,"code":115,"language":16,"meta":116,"style":116},"language-javascript shiki shiki-themes github-light github-dark","test(\"processOrder marks the order as paid\", async () => {\n  const cart = new InMemoryCart([{ sku: \"A1\", price: 20 }]);\n  const gateway = new FakePaymentGateway({ willSucceed: true });\n\n  const order = await processOrder(cart, gateway);\n\n  expect(order.status).toBe(\"paid\");\n});\n","",[84,118,119,152,186,210,216,235,240,259],{"__ignoreMap":116},[120,121,124,128,132,136,139,143,146,149],"span",{"class":122,"line":123},"line",1,[120,125,127],{"class":126},"sIsaT","test",[120,129,131],{"class":130},"ssxIu","(",[120,133,135],{"class":134},"sJ6F3","\"processOrder marks the order as paid\"",[120,137,138],{"class":130},", ",[120,140,142],{"class":141},"svdQ7","async",[120,144,145],{"class":130}," () ",[120,147,148],{"class":141},"=>",[120,150,151],{"class":130}," {\n",[120,153,155,158,162,165,168,171,174,177,180,183],{"class":122,"line":154},2,[120,156,157],{"class":141},"  const",[120,159,161],{"class":160},"snvgF"," cart",[120,163,164],{"class":141}," =",[120,166,167],{"class":141}," new",[120,169,170],{"class":126}," InMemoryCart",[120,172,173],{"class":130},"([{ sku: ",[120,175,176],{"class":134},"\"A1\"",[120,178,179],{"class":130},", price: ",[120,181,182],{"class":160},"20",[120,184,185],{"class":130}," }]);\n",[120,187,189,191,194,196,198,201,204,207],{"class":122,"line":188},3,[120,190,157],{"class":141},[120,192,193],{"class":160}," gateway",[120,195,164],{"class":141},[120,197,167],{"class":141},[120,199,200],{"class":126}," FakePaymentGateway",[120,202,203],{"class":130},"({ willSucceed: ",[120,205,206],{"class":160},"true",[120,208,209],{"class":130}," });\n",[120,211,213],{"class":122,"line":212},4,[120,214,215],{"emptyLinePlaceholder":35},"\n",[120,217,219,221,224,226,229,232],{"class":122,"line":218},5,[120,220,157],{"class":141},[120,222,223],{"class":160}," order",[120,225,164],{"class":141},[120,227,228],{"class":141}," await",[120,230,231],{"class":126}," processOrder",[120,233,234],{"class":130},"(cart, gateway);\n",[120,236,238],{"class":122,"line":237},6,[120,239,215],{"emptyLinePlaceholder":35},[120,241,243,246,249,252,254,256],{"class":122,"line":242},7,[120,244,245],{"class":126},"  expect",[120,247,248],{"class":130},"(order.status).",[120,250,251],{"class":126},"toBe",[120,253,131],{"class":130},[120,255,106],{"class":134},[120,257,258],{"class":130},");\n",[120,260,262],{"class":122,"line":261},8,[120,263,264],{"class":130},"});\n",[23,266,268,274,283,295],{"className":267},[26],[28,269,271,273],{"className":270},[31],[33,272],{"disabled":35,"type":36}," End-to-end test — it exercises the full application exactly the way a real user would, including the actual UI and a live payment gateway",[28,275,277,279,280,282],{"className":276},[31],[33,278],{"disabled":35,"type":36}," Unit test — because ",[84,281,98],{}," is a single function, calling it in a test always makes the test a unit test regardless of what it depends on",[28,284,286,288,289,291,292,294],{"className":285},[31],[33,287],{"disabled":35,"type":36}," Integration test — it exercises ",[84,290,98],{}," together with its collaborators (the cart and the payment gateway, even though the gateway is a fake), verifying that these pieces work correctly together rather than testing ",[84,293,98],{}," in full isolation or driving the app through a real UI",[28,296,298,300,301,304],{"className":297},[31],[33,299],{"disabled":35,"type":36}," Snapshot test — because the assertion checks the resulting ",[84,302,303],{},"order"," object's shape",[57,306,307,309,318],{},[60,308,62],{},[64,310,311,313,314,291,316,294],{},[67,312,69],{}," C — Integration test — it exercises ",[84,315,98],{},[84,317,98],{},[64,319,320,322],{},[67,321,75],{}," What makes this an integration test is that the assertion depends on the correct interaction between multiple collaborating pieces (cart totaling, order state transitions, gateway charging), even though the gateway is faked rather than real. Option A is wrong because there's no browser, UI, or live network call involved — using fakes instead of the real UI is exactly what keeps this out of E2E territory. Option B is the common misconception that \"one function call\" automatically means \"unit test\"; what matters is whether the collaborators are isolated out (unit) or exercised together (integration), not how many function calls appear in the test body. Option D confuses this with snapshot testing, which serializes and diffs output rather than asserting on a specific field.",[14,324,325,329,356],{},[18,326,328],{"id":327},"q3-which-statement-accurately-distinguishes-a-spy-a-stub-and-a-mock","Q3. Which statement accurately distinguishes a spy, a stub, and a mock?",[23,330,332,338,344,350],{"className":331},[26],[28,333,335,337],{"className":334},[31],[33,336],{"disabled":35,"type":36}," A spy wraps a real function, recording calls (arguments, call count) while still invoking the original implementation; a stub replaces a function with fixed, canned behavior; a mock is a stub that also has built-in expectations\u002Fassertions about how it should be called",[28,339,341,343],{"className":340},[31],[33,342],{"disabled":35,"type":36}," A stub wraps a real function and records how it was called while still invoking the original implementation",[28,345,347,349],{"className":346},[31],[33,348],{"disabled":35,"type":36}," A mock always requires a real network connection to verify calls",[28,351,353,355],{"className":352},[31],[33,354],{"disabled":35,"type":36}," Spies, stubs, and mocks are interchangeable terms with no meaningful difference between testing libraries",[57,357,358,360,365],{},[60,359,62],{},[64,361,362,364],{},[67,363,69],{}," A — A spy wraps a real function, recording calls (arguments, call count) while still invoking the original implementation; a stub replaces a function with fixed, canned behavior; a mock is a stub that also has built-in expectations\u002Fassertions about how it should be called",[64,366,367,369,370,373,374,377,378,381,382,377,385,388],{},[67,368,75],{}," ",[67,371,372],{},"Idiom:"," these three terms describe increasing levels of replacement and assertion, and the distinction is universal test-double terminology, not specific to any one framework — Jest's ",[84,375,376],{},"jest.fn()","\u002F",[84,379,380],{},"jest.spyOn()"," and Vitest's ",[84,383,384],{},"vi.fn()",[84,386,387],{},"vi.spyOn()"," are just two libraries' names for building spies, stubs, and mocks. A spy observes without necessarily replacing behavior; a stub replaces behavior with something canned so the test controls the return value; a mock goes further by encoding expectations about the calls themselves (e.g. \"was called exactly once with these arguments\") as part of the double. Option B swaps the spy\u002Fstub definitions. Option C and D are simply false — none of these concepts require real network access, and the distinctions materially affect how a test reads and what it actually proves.",[14,390,391,403,463,502],{"language":16},[18,392,394,395,398,399,402],{"id":393},"q4-jestspyonconsole-error-is-called-with-no-mockimplementation-chained-after-it-what-happens-when-the-spied-method-is-invoked-during-the-test","Q4. ",[84,396,397],{},"jest.spyOn(console, \"error\")"," is called with no ",[84,400,401],{},".mockImplementation(...)"," chained after it. What happens when the spied method is invoked during the test?",[109,404,405],{"language":16},[112,406,408],{"className":114,"code":407,"language":16,"meta":116,"style":116},"const spy = jest.spyOn(console, \"error\");\n\ndoSomethingThatLogsAnError();\n\nexpect(spy).toHaveBeenCalled();\n",[84,409,410,434,438,446,450],{"__ignoreMap":116},[120,411,412,415,418,420,423,426,429,432],{"class":122,"line":123},[120,413,414],{"class":141},"const",[120,416,417],{"class":160}," spy",[120,419,164],{"class":141},[120,421,422],{"class":130}," jest.",[120,424,425],{"class":126},"spyOn",[120,427,428],{"class":130},"(console, ",[120,430,431],{"class":134},"\"error\"",[120,433,258],{"class":130},[120,435,436],{"class":122,"line":154},[120,437,215],{"emptyLinePlaceholder":35},[120,439,440,443],{"class":122,"line":188},[120,441,442],{"class":126},"doSomethingThatLogsAnError",[120,444,445],{"class":130},"();\n",[120,447,448],{"class":122,"line":212},[120,449,215],{"emptyLinePlaceholder":35},[120,451,452,455,458,461],{"class":122,"line":218},[120,453,454],{"class":126},"expect",[120,456,457],{"class":130},"(spy).",[120,459,460],{"class":126},"toHaveBeenCalled",[120,462,445],{"class":130},[23,464,466,475,487,493],{"className":465},[26],[28,467,469,369,471,474],{"className":468},[31],[33,470],{"disabled":35,"type":36},[84,472,473],{},"console.error"," is completely silenced; nothing is printed to the console",[28,476,478,369,480,483,484,486],{"className":477},[31],[33,479],{"disabled":35,"type":36},[84,481,482],{},"jest.spyOn"," throws because ",[84,485,473],{}," cannot be spied on",[28,488,490,492],{"className":489},[31],[33,491],{"disabled":35,"type":36}," The test fails immediately, because spies cannot wrap built-in global methods",[28,494,496,498,499,501],{"className":495},[31],[33,497],{"disabled":35,"type":36}," The spy records the call for the assertion, but ",[84,500,473],{}," still executes its real implementation, so the error is still printed to the console",[57,503,504,506,513],{},[60,505,62],{},[64,507,508,510,511,501],{},[67,509,69],{}," D — The spy records the call for the assertion, but ",[84,512,473],{},[64,514,515,369,517,520,521,524,525,527,528,531,532,534,535,538],{},[67,516,75],{},[67,518,519],{},"Debug:"," a bare ",[84,522,523],{},"jest.spyOn(obj, \"method\")"," call, by default, calls through to the real implementation — it only adds tracking of calls, arguments, and return values on top. To also replace the behavior (e.g. to silence noisy ",[84,526,473],{}," output in a test), you must explicitly chain ",[84,529,530],{},".mockImplementation(() => {})",". Option A is the mistake many people make: assuming spying automatically suppresses output, when in fact suppression requires an explicit mock implementation. Options B and C are false — ",[84,533,482],{}," works on object methods including built-ins like ",[84,536,537],{},"console",", as long as the property is configurable.",[14,540,541,545,624,680],{"language":16},[18,542,544],{"id":543},"q5-what-is-the-problem-with-this-test","Q5. What is the problem with this test?",[109,546,547],{"language":16},[112,548,550],{"className":114,"code":549,"language":16,"meta":116,"style":116},"test(\"fetchUser resolves with the right name\", () => {\n  fetchUser(1).then((user) => {\n    expect(user.name).toBe(\"Ada\");\n  });\n});\n",[84,551,552,568,598,615,620],{"__ignoreMap":116},[120,553,554,556,558,561,564,566],{"class":122,"line":123},[120,555,127],{"class":126},[120,557,131],{"class":130},[120,559,560],{"class":134},"\"fetchUser resolves with the right name\"",[120,562,563],{"class":130},", () ",[120,565,148],{"class":141},[120,567,151],{"class":130},[120,569,570,573,575,578,581,584,587,591,594,596],{"class":122,"line":154},[120,571,572],{"class":126},"  fetchUser",[120,574,131],{"class":130},[120,576,577],{"class":160},"1",[120,579,580],{"class":130},").",[120,582,583],{"class":126},"then",[120,585,586],{"class":130},"((",[120,588,590],{"class":589},"sCrzJ","user",[120,592,593],{"class":130},") ",[120,595,148],{"class":141},[120,597,151],{"class":130},[120,599,600,603,606,608,610,613],{"class":122,"line":188},[120,601,602],{"class":126},"    expect",[120,604,605],{"class":130},"(user.name).",[120,607,251],{"class":126},[120,609,131],{"class":130},[120,611,612],{"class":134},"\"Ada\"",[120,614,258],{"class":130},[120,616,617],{"class":122,"line":212},[120,618,619],{"class":130},"  });\n",[120,621,622],{"class":122,"line":218},[120,623,264],{"class":130},[23,625,627,637,661,674],{"className":626},[26],[28,628,630,632,633,636],{"className":629},[31],[33,631],{"disabled":35,"type":36}," This test always fails, because ",[84,634,635],{},"fetchUser"," returns a promise instead of a value",[28,638,640,642,643,646,647,649,650,653,654,657,658,660],{"className":639},[31],[33,641],{"disabled":35,"type":36}," This test can report as passing even if ",[84,644,645],{},"user.name"," is not ",[84,648,612],{},", because the test function returns ",[84,651,652],{},"undefined"," synchronously and the test runner considers the test done before the ",[84,655,656],{},".then()"," callback — and its ",[84,659,454],{}," — ever runs",[28,662,664,666,667,669,670,673],{"className":663},[31],[33,665],{"disabled":35,"type":36}," This test throws a syntax error, because ",[84,668,656],{}," cannot be used inside a ",[84,671,672],{},"test()"," callback",[28,675,677,679],{"className":676},[31],[33,678],{"disabled":35,"type":36}," This test correctly verifies the resolved value; the test runner automatically waits for any promise created inside a test",[57,681,682,684,699],{},[60,683,62],{},[64,685,686,688,689,646,691,649,693,653,695,657,697,660],{},[67,687,69],{}," B — This test can report as passing even if ",[84,690,645],{},[84,692,612],{},[84,694,652],{},[84,696,656],{},[84,698,454],{},[64,700,701,369,703,705,706,708,709,712,713,715,716,720,721,723,724,727,728,731],{},[67,702,75],{},[67,704,519],{}," this is one of the most common silent-false-positive bugs in async testing. The test callback here is a plain synchronous function that returns ",[84,707,652],{}," immediately; Jest and Vitest both mark a test complete as soon as its callback returns (unless it returns a promise or uses a ",[84,710,711],{},"done"," parameter). The ",[84,714,656],{}," callback is scheduled as a microtask that runs ",[717,718,719],"em",{},"after"," the synchronous test function has already returned, so if the ",[84,722,454],{}," inside it fails, that failure either gets reported as an unhandled rejection after the test has already \"passed,\" or is missed entirely depending on runner configuration. The fix is to ",[84,725,726],{},"return fetchUser(1).then(...)"," or, more idiomatically, use ",[84,729,730],{},"async () => { const user = await fetchUser(1); expect(user.name).toBe(\"Ada\"); }",".",[14,733,734,738,860,924],{"language":16},[18,735,737],{"id":736},"q6-what-is-wrong-with-this-test","Q6. What is wrong with this test?",[109,739,740],{"language":16},[112,741,743],{"className":114,"code":742,"language":16,"meta":116,"style":116},"test(\"all users are validated\", async () => {\n  const ids = [1, 2, 3];\n\n  ids.forEach(async (id) => {\n    const user = await fetchUser(id);\n    expect(user.isValid).toBe(true);\n  });\n});\n",[84,744,745,764,791,795,819,837,852,856],{"__ignoreMap":116},[120,746,747,749,751,754,756,758,760,762],{"class":122,"line":123},[120,748,127],{"class":126},[120,750,131],{"class":130},[120,752,753],{"class":134},"\"all users are validated\"",[120,755,138],{"class":130},[120,757,142],{"class":141},[120,759,145],{"class":130},[120,761,148],{"class":141},[120,763,151],{"class":130},[120,765,766,768,771,773,776,778,780,783,785,788],{"class":122,"line":154},[120,767,157],{"class":141},[120,769,770],{"class":160}," ids",[120,772,164],{"class":141},[120,774,775],{"class":130}," [",[120,777,577],{"class":160},[120,779,138],{"class":130},[120,781,782],{"class":160},"2",[120,784,138],{"class":130},[120,786,787],{"class":160},"3",[120,789,790],{"class":130},"];\n",[120,792,793],{"class":122,"line":188},[120,794,215],{"emptyLinePlaceholder":35},[120,796,797,800,803,805,807,810,813,815,817],{"class":122,"line":212},[120,798,799],{"class":130},"  ids.",[120,801,802],{"class":126},"forEach",[120,804,131],{"class":130},[120,806,142],{"class":141},[120,808,809],{"class":130}," (",[120,811,812],{"class":589},"id",[120,814,593],{"class":130},[120,816,148],{"class":141},[120,818,151],{"class":130},[120,820,821,824,827,829,831,834],{"class":122,"line":218},[120,822,823],{"class":141},"    const",[120,825,826],{"class":160}," user",[120,828,164],{"class":141},[120,830,228],{"class":141},[120,832,833],{"class":126}," fetchUser",[120,835,836],{"class":130},"(id);\n",[120,838,839,841,844,846,848,850],{"class":122,"line":237},[120,840,602],{"class":126},[120,842,843],{"class":130},"(user.isValid).",[120,845,251],{"class":126},[120,847,131],{"class":130},[120,849,206],{"class":160},[120,851,258],{"class":130},[120,853,854],{"class":122,"line":242},[120,855,619],{"class":130},[120,857,858],{"class":122,"line":261},[120,859,264],{"class":130},[23,861,863,878,897,910],{"className":862},[26],[28,864,866,369,868,871,872,874,875,877],{"className":865},[31],[33,867],{"disabled":35,"type":36},[84,869,870],{},"Array.prototype.forEach"," does not await the async callbacks it's given, so the outer test function returns (and the test is marked done) before any of the ",[84,873,635],{}," calls resolve or their ",[84,876,454],{}," calls actually run",[28,879,881,883,884,886,887,889,890,893,894,896],{"className":880},[31],[33,882],{"disabled":35,"type":36}," This is correct — ",[84,885,142],{}," inside ",[84,888,802],{}," makes the whole loop asynchronous, and ",[84,891,892],{},"await"," on the outer ",[84,895,127],{}," waits for every iteration to finish before the test completes",[28,898,900,902,903,906,907,909],{"className":899},[31],[33,901],{"disabled":35,"type":36}," This throws a ",[84,904,905],{},"TypeError",", because ",[84,908,802],{}," cannot accept an async function",[28,911,913,915,916,919,920,923],{"className":912},[31],[33,914],{"disabled":35,"type":36}," This is equivalent to using ",[84,917,918],{},"Promise.all"," with ",[84,921,922],{},"map",", so all assertions are guaranteed to run before the test finishes",[57,925,926,928,939],{},[60,927,62],{},[64,929,930,932,933,871,935,874,937,877],{},[67,931,69],{}," A — ",[84,934,870],{},[84,936,635],{},[84,938,454],{},[64,940,941,369,943,369,945,947,948,951,952,954,955,957,958,960,961,963,964,966,967,970,971,974],{},[67,942,75],{},[67,944,519],{},[84,946,802],{}," invokes its callback for each element and completely ignores any value — including a promise — that the callback returns; it does not chain or await them. Each ",[84,949,950],{},"async (id) => {...}"," call kicks off a promise and ",[84,953,802],{}," immediately moves to the next element without waiting, so the outer ",[84,956,127],{}," function's ",[84,959,892],{},"-free body returns right after the loop, and the test is considered finished before any ",[84,962,635],{}," resolves. This makes every ",[84,965,454],{}," inside the loop a fire-and-forget check that may never be seen by the test runner. The fix is ",[84,968,969],{},"for (const id of ids) { const user = await fetchUser(id); expect(user.isValid).toBe(true); }",", or ",[84,972,973],{},"await Promise.all(ids.map(async (id) => { ... }))",". Option D specifically names the correct fix pattern but wrongly claims it describes the code as written.",[14,976,977,981,1056,1091],{"language":16},[18,978,980],{"id":979},"q7-given-this-function-which-is-the-most-correct-way-to-test-that-it-rejects-for-an-invalid-amount","Q7. Given this function, which is the most correct way to test that it rejects for an invalid amount?",[109,982,983],{"language":16},[112,984,986],{"className":114,"code":985,"language":16,"meta":116,"style":116},"async function chargeCard(amount) {\n  if (amount \u003C= 0) throw new Error(\"Invalid amount\");\n  return gateway.charge(amount);\n}\n",[84,987,988,1006,1037,1051],{"__ignoreMap":116},[120,989,990,992,995,998,1000,1003],{"class":122,"line":123},[120,991,142],{"class":141},[120,993,994],{"class":141}," function",[120,996,997],{"class":126}," chargeCard",[120,999,131],{"class":130},[120,1001,1002],{"class":589},"amount",[120,1004,1005],{"class":130},") {\n",[120,1007,1008,1011,1014,1017,1020,1022,1025,1027,1030,1032,1035],{"class":122,"line":154},[120,1009,1010],{"class":141},"  if",[120,1012,1013],{"class":130}," (amount ",[120,1015,1016],{"class":141},"\u003C=",[120,1018,1019],{"class":160}," 0",[120,1021,593],{"class":130},[120,1023,1024],{"class":141},"throw",[120,1026,167],{"class":141},[120,1028,1029],{"class":126}," Error",[120,1031,131],{"class":130},[120,1033,1034],{"class":134},"\"Invalid amount\"",[120,1036,258],{"class":130},[120,1038,1039,1042,1045,1048],{"class":122,"line":188},[120,1040,1041],{"class":141},"  return",[120,1043,1044],{"class":130}," gateway.",[120,1046,1047],{"class":126},"charge",[120,1049,1050],{"class":130},"(amount);\n",[120,1052,1053],{"class":122,"line":212},[120,1054,1055],{"class":130},"}\n",[23,1057,1059,1067,1075,1083],{"className":1058},[26],[28,1060,1062,369,1064],{"className":1061},[31],[33,1063],{"disabled":35,"type":36},[84,1065,1066],{},"expect(chargeCard(-5)).toThrow(\"Invalid amount\");",[28,1068,1070,369,1072],{"className":1069},[31],[33,1071],{"disabled":35,"type":36},[84,1073,1074],{},"const result = chargeCard(-5); expect(result).toBe(undefined);",[28,1076,1078,369,1080],{"className":1077},[31],[33,1079],{"disabled":35,"type":36},[84,1081,1082],{},"chargeCard(-5).catch((e) => console.log(e));",[28,1084,1086,369,1088],{"className":1085},[31],[33,1087],{"disabled":35,"type":36},[84,1089,1090],{},"await expect(chargeCard(-5)).rejects.toThrow(\"Invalid amount\");",[57,1092,1093,1095,1102],{},[60,1094,62],{},[64,1096,1097,1099,1100],{},[67,1098,69],{}," D — ",[84,1101,1090],{},[64,1103,1104,369,1106,369,1108,1111,1112,1115,1116,377,1119,1122,1123,1126,1127,1129,1130,1133,1134,1137],{},[67,1105,75],{},[67,1107,372],{},[84,1109,1110],{},".rejects"," unwraps the promise's rejection so the matcher can assert on the thrown error, and awaiting the whole ",[84,1113,1114],{},"expect(...)"," call ensures the test runner actually waits for that assertion to run before the test is marked complete. (",[84,1117,1118],{},"rejects",[84,1120,1121],{},"resolves"," are Jest and Vitest matcher-naming conventions specifically — other runners use different syntax, but the underlying need to both await and assert on the rejection is universal.) Option A is wrong because ",[84,1124,1125],{},"toThrow"," expects a synchronously-throwing function, not a promise — an async function's ",[84,1128,1024],{}," becomes a rejection, not a synchronous exception, so this assertion doesn't correctly observe it. Option B never awaits anything and doesn't test failure at all. Option C swallows the rejection with a ",[84,1131,1132],{},"console.log"," and asserts nothing — if ",[84,1135,1136],{},"chargeCard"," unexpectedly resolved instead of rejecting, this \"test\" would still report as passing.",[14,1139,1140,1144,1229,1284],{"language":16},[18,1141,1143],{"id":1142},"q8-what-is-the-risk-in-this-test","Q8. What is the risk in this test?",[109,1145,1146],{"language":16},[112,1147,1149],{"className":114,"code":1148,"language":16,"meta":116,"style":116},"test(\"chargeCard rejects for invalid amount\", async () => {\n  try {\n    await chargeCard(-5);\n  } catch (err) {\n    expect(err.message).toBe(\"Invalid amount\");\n  }\n});\n",[84,1150,1151,1170,1177,1194,1205,1220,1225],{"__ignoreMap":116},[120,1152,1153,1155,1157,1160,1162,1164,1166,1168],{"class":122,"line":123},[120,1154,127],{"class":126},[120,1156,131],{"class":130},[120,1158,1159],{"class":134},"\"chargeCard rejects for invalid amount\"",[120,1161,138],{"class":130},[120,1163,142],{"class":141},[120,1165,145],{"class":130},[120,1167,148],{"class":141},[120,1169,151],{"class":130},[120,1171,1172,1175],{"class":122,"line":154},[120,1173,1174],{"class":141},"  try",[120,1176,151],{"class":130},[120,1178,1179,1182,1184,1186,1189,1192],{"class":122,"line":188},[120,1180,1181],{"class":141},"    await",[120,1183,997],{"class":126},[120,1185,131],{"class":130},[120,1187,1188],{"class":141},"-",[120,1190,1191],{"class":160},"5",[120,1193,258],{"class":130},[120,1195,1196,1199,1202],{"class":122,"line":212},[120,1197,1198],{"class":130},"  } ",[120,1200,1201],{"class":141},"catch",[120,1203,1204],{"class":130}," (err) {\n",[120,1206,1207,1209,1212,1214,1216,1218],{"class":122,"line":218},[120,1208,602],{"class":126},[120,1210,1211],{"class":130},"(err.message).",[120,1213,251],{"class":126},[120,1215,131],{"class":130},[120,1217,1034],{"class":134},[120,1219,258],{"class":130},[120,1221,1222],{"class":122,"line":237},[120,1223,1224],{"class":130},"  }\n",[120,1226,1227],{"class":122,"line":242},[120,1228,264],{"class":130},[23,1230,1232,1241,1253,1269],{"className":1231},[26],[28,1233,1235,1237,1238],{"className":1234},[31],[33,1236],{"disabled":35,"type":36}," This is the recommended pattern for testing rejections; it is equivalent in safety to ",[84,1239,1240],{},"rejects.toThrow",[28,1242,1244,1246,1247,1249,1250,1252],{"className":1243},[31],[33,1245],{"disabled":35,"type":36}," This throws a syntax error, because ",[84,1248,454],{}," cannot be called inside a ",[84,1251,1201],{}," block",[28,1254,1256,1258,1259,1262,1263,1265,1266,1268],{"className":1255},[31],[33,1257],{"disabled":35,"type":36}," This test can give a false positive: if ",[84,1260,1261],{},"chargeCard(-5)"," unexpectedly resolves instead of rejecting, the ",[84,1264,1201],{}," block — and its ",[84,1267,454],{}," — never runs, and the test passes having executed zero assertions",[28,1270,1272,632,1274,377,1277,1279,1280,377,1282],{"className":1271},[31],[33,1273],{"disabled":35,"type":36},[84,1275,1276],{},"try",[84,1278,1201],{}," cannot be combined with ",[84,1281,142],{},[84,1283,892],{},[57,1285,1286,1288,1299],{},[60,1287,62],{},[64,1289,1290,1292,1293,1262,1295,1265,1297,1268],{},[67,1291,69],{}," C — This test can give a false positive: if ",[84,1294,1261],{},[84,1296,1201],{},[84,1298,454],{},[64,1300,1301,369,1303,1305,1306,377,1308,1310,1311,377,1313,1315,1316,1318,1319,1321,1322,1324,1325,1328,1329,1332],{},[67,1302,75],{},[67,1304,519],{}," this is the same silent-false-positive family as the missing-",[84,1307,892],{},[84,1309,656],{}," bug, just wearing a ",[84,1312,1276],{},[84,1314,1201],{}," disguise. If a future change accidentally makes ",[84,1317,1136],{}," resolve for negative amounts instead of throwing, the ",[84,1320,1201],{}," block simply never executes, no ",[84,1323,454],{}," ever runs, and the test still reports green — precisely when it should be failing loudest. The safer pattern is ",[84,1326,1327],{},"await expect(chargeCard(-5)).rejects.toThrow(\"Invalid amount\")",", where the absence of a rejection itself causes the assertion to fail; alternatively, guard the try\u002Fcatch version with ",[84,1330,1331],{},"expect.assertions(1)"," at the top of the test so the runner fails the test if the expected number of assertions never ran.",[14,1334,1335,1339,1414,1441],{"language":16},[18,1336,1338],{"id":1337},"q9-what-tradeoff-does-snapshot-testing-introduce","Q9. What tradeoff does snapshot testing introduce?",[109,1340,1341],{"language":16},[112,1342,1344],{"className":114,"code":1343,"language":16,"meta":116,"style":116},"test(\"renders the user card\", () => {\n  const tree = renderer.create(\u003CUserCard name=\"Ada\" \u002F>).toJSON();\n  expect(tree).toMatchSnapshot();\n});\n",[84,1345,1346,1361,1398,1410],{"__ignoreMap":116},[120,1347,1348,1350,1352,1355,1357,1359],{"class":122,"line":123},[120,1349,127],{"class":126},[120,1351,131],{"class":130},[120,1353,1354],{"class":134},"\"renders the user card\"",[120,1356,563],{"class":130},[120,1358,148],{"class":141},[120,1360,151],{"class":130},[120,1362,1363,1365,1368,1370,1373,1376,1379,1382,1385,1388,1390,1393,1396],{"class":122,"line":154},[120,1364,157],{"class":141},[120,1366,1367],{"class":160}," tree",[120,1369,164],{"class":141},[120,1371,1372],{"class":130}," renderer.",[120,1374,1375],{"class":126},"create",[120,1377,1378],{"class":130},"(\u003C",[120,1380,1381],{"class":160},"UserCard",[120,1383,1384],{"class":126}," name",[120,1386,1387],{"class":141},"=",[120,1389,612],{"class":134},[120,1391,1392],{"class":130}," \u002F>).",[120,1394,1395],{"class":126},"toJSON",[120,1397,445],{"class":130},[120,1399,1400,1402,1405,1408],{"class":122,"line":188},[120,1401,245],{"class":126},[120,1403,1404],{"class":130},"(tree).",[120,1406,1407],{"class":126},"toMatchSnapshot",[120,1409,445],{"class":130},[120,1411,1412],{"class":122,"line":212},[120,1413,264],{"class":130},[23,1415,1417,1423,1429,1435],{"className":1416},[26],[28,1418,1420,1422],{"className":1419},[31],[33,1421],{"disabled":35,"type":36}," Snapshot tests replace the need for any other assertions, because they capture the entire output automatically",[28,1424,1426,1428],{"className":1425},[31],[33,1427],{"disabled":35,"type":36}," Snapshot tests are useful for catching unintended changes to output, but they carry a real risk: when a snapshot fails, it's easy to reflexively run the \"update snapshot\" command without actually reviewing the diff, which can silently bake a real regression into the new snapshot as the new \"expected\" output",[28,1430,1432,1434],{"className":1431},[31],[33,1433],{"disabled":35,"type":36}," Snapshots can only be used with React components, never with plain JSON or string output",[28,1436,1438,1440],{"className":1437},[31],[33,1439],{"disabled":35,"type":36}," A snapshot test fails only if the component throws an error during render",[57,1442,1443,1445,1450],{},[60,1444,62],{},[64,1446,1447,1449],{},[67,1448,69],{}," B — Snapshot tests are useful for catching unintended changes to output, but they carry a real risk: when a snapshot fails, it's easy to reflexively run the \"update snapshot\" command without actually reviewing the diff, which can silently bake a real regression into the new snapshot as the new \"expected\" output",[64,1451,1452,1454,1455,1458,1459,1462,1463,1466,1467,1469],{},[67,1453,75],{}," Snapshot testing is good at flagging ",[717,1456,1457],{},"that"," output changed, but says nothing about whether the change is correct — that judgment call is left entirely to whoever reviews the failing diff. In practice, a failing snapshot in a busy CI run often gets \"fixed\" by blindly re-running the updater, which overwrites the stored snapshot with whatever the (possibly buggy) code now produces, turning a real regression into the new passing baseline. Option A overstates what snapshots verify — they detect ",[717,1460,1461],{},"change",", not ",[717,1464,1465],{},"correctness",". Option C is false; ",[84,1468,1407],{}," works on any serializable value, including plain objects and strings. Option D is false; a snapshot test fails whenever the serialized output differs from the stored snapshot, render errors aside.",[14,1471,1472,1476,1503],{},[18,1473,1475],{"id":1474},"q10-following-on-from-snapshot-testing-what-is-the-correct-discipline-for-handling-a-failing-snapshot","Q10. Following on from snapshot testing: what is the correct discipline for handling a failing snapshot?",[23,1477,1479,1485,1491,1497],{"className":1478},[26],[28,1480,1482,1484],{"className":1481},[31],[33,1483],{"disabled":35,"type":36}," Snapshots should be reviewed like a code diff on every failure — treating an unreviewed \"update snapshot\" run as automatically correct defeats the purpose of the test, since it just captures whatever the code currently outputs as the new \"truth\"",[28,1486,1488,1490],{"className":1487},[31],[33,1489],{"disabled":35,"type":36}," It is always safe to run the snapshot-update command in CI on every failing build, to keep the suite green",[28,1492,1494,1496],{"className":1493},[31],[33,1495],{"disabled":35,"type":36}," Snapshots should be committed as binary files, so they cannot be diffed or reviewed at all",[28,1498,1500,1502],{"className":1499},[31],[33,1501],{"disabled":35,"type":36}," A growing snapshot file is a sign the test suite has too much coverage, and snapshots should be deleted regularly",[57,1504,1505,1507,1512],{},[60,1506,62],{},[64,1508,1509,1511],{},[67,1510,69],{}," A — Snapshots should be reviewed like a code diff on every failure — treating an unreviewed \"update snapshot\" run as automatically correct defeats the purpose of the test, since it just captures whatever the code currently outputs as the new \"truth\"",[64,1513,1514,1516,1517,1520],{},[67,1515,75],{}," A snapshot is only as trustworthy as the review it received when it was captured or updated; the entire value of the test collapses if updates are applied reflexively rather than read as a diff. Option B describes the exact anti-pattern that turns a regression detector into rubber-stamping machinery — automatically updating snapshots in CI removes the human review step that gives the test any signal at all. Option C is counterproductive; snapshots are stored as plain, diffable text (e.g. ",[84,1518,1519],{},".snap"," files) specifically so they can be reviewed in pull requests. Option D confuses volume with quality — a large snapshot file isn't inherently a problem, but unreviewed updates are.",[14,1522,1523,1527,1694,1735],{"language":16},[18,1524,1526],{"id":1525},"q11-what-is-the-problem-with-this-pair-of-tests","Q11. What is the problem with this pair of tests?",[109,1528,1529],{"language":16},[112,1530,1532],{"className":114,"code":1531,"language":16,"meta":116,"style":116},"let cache = [];\n\nfunction addItem(item) {\n  cache.push(item);\n  return cache.length;\n}\n\ntest(\"adds first item\", () => {\n  expect(addItem(\"a\")).toBe(1);\n});\n\ntest(\"adds second item\", () => {\n  expect(addItem(\"b\")).toBe(1);\n});\n",[84,1533,1534,1547,1551,1566,1577,1590,1594,1598,1613,1639,1644,1649,1665,1689],{"__ignoreMap":116},[120,1535,1536,1539,1542,1544],{"class":122,"line":123},[120,1537,1538],{"class":141},"let",[120,1540,1541],{"class":130}," cache ",[120,1543,1387],{"class":141},[120,1545,1546],{"class":130}," [];\n",[120,1548,1549],{"class":122,"line":154},[120,1550,215],{"emptyLinePlaceholder":35},[120,1552,1553,1556,1559,1561,1564],{"class":122,"line":188},[120,1554,1555],{"class":141},"function",[120,1557,1558],{"class":126}," addItem",[120,1560,131],{"class":130},[120,1562,1563],{"class":589},"item",[120,1565,1005],{"class":130},[120,1567,1568,1571,1574],{"class":122,"line":212},[120,1569,1570],{"class":130},"  cache.",[120,1572,1573],{"class":126},"push",[120,1575,1576],{"class":130},"(item);\n",[120,1578,1579,1581,1584,1587],{"class":122,"line":218},[120,1580,1041],{"class":141},[120,1582,1583],{"class":130}," cache.",[120,1585,1586],{"class":160},"length",[120,1588,1589],{"class":130},";\n",[120,1591,1592],{"class":122,"line":237},[120,1593,1055],{"class":130},[120,1595,1596],{"class":122,"line":242},[120,1597,215],{"emptyLinePlaceholder":35},[120,1599,1600,1602,1604,1607,1609,1611],{"class":122,"line":261},[120,1601,127],{"class":126},[120,1603,131],{"class":130},[120,1605,1606],{"class":134},"\"adds first item\"",[120,1608,563],{"class":130},[120,1610,148],{"class":141},[120,1612,151],{"class":130},[120,1614,1616,1618,1620,1623,1625,1628,1631,1633,1635,1637],{"class":122,"line":1615},9,[120,1617,245],{"class":126},[120,1619,131],{"class":130},[120,1621,1622],{"class":126},"addItem",[120,1624,131],{"class":130},[120,1626,1627],{"class":134},"\"a\"",[120,1629,1630],{"class":130},")).",[120,1632,251],{"class":126},[120,1634,131],{"class":130},[120,1636,577],{"class":160},[120,1638,258],{"class":130},[120,1640,1642],{"class":122,"line":1641},10,[120,1643,264],{"class":130},[120,1645,1647],{"class":122,"line":1646},11,[120,1648,215],{"emptyLinePlaceholder":35},[120,1650,1652,1654,1656,1659,1661,1663],{"class":122,"line":1651},12,[120,1653,127],{"class":126},[120,1655,131],{"class":130},[120,1657,1658],{"class":134},"\"adds second item\"",[120,1660,563],{"class":130},[120,1662,148],{"class":141},[120,1664,151],{"class":130},[120,1666,1668,1670,1672,1674,1676,1679,1681,1683,1685,1687],{"class":122,"line":1667},13,[120,1669,245],{"class":126},[120,1671,131],{"class":130},[120,1673,1622],{"class":126},[120,1675,131],{"class":130},[120,1677,1678],{"class":134},"\"b\"",[120,1680,1630],{"class":130},[120,1682,251],{"class":126},[120,1684,131],{"class":130},[120,1686,577],{"class":160},[120,1688,258],{"class":130},[120,1690,1692],{"class":122,"line":1691},14,[120,1693,264],{"class":130},[23,1695,1697,1703,1712,1726],{"className":1696},[26],[28,1698,1700,1702],{"className":1699},[31],[33,1701],{"disabled":35,"type":36}," Both tests pass reliably regardless of run order, because the test runner resets all module-level variables before each test",[28,1704,1706,1708,1709,1711],{"className":1705},[31],[33,1707],{"disabled":35,"type":36}," This code cannot run at all, because top-level ",[84,1710,1538],{}," declarations are forbidden in test files",[28,1713,1715,1717,1718,906,1720,1723,1724],{"className":1714},[31],[33,1716],{"disabled":35,"type":36}," The second test always fails with a ",[84,1719,905],{},[84,1721,1722],{},"cache"," is undefined inside ",[84,1725,1622],{},[28,1727,1729,1731,1732,1734],{"className":1728},[31],[33,1730],{"disabled":35,"type":36}," The second test is order-dependent and will fail (or pass) unpredictably depending on execution order, because ",[84,1733,1722],{}," is module-level shared state that isn't reset between tests — a classic source of flaky, order-dependent failures",[57,1736,1737,1739,1746],{},[60,1738,62],{},[64,1740,1741,1743,1744,1734],{},[67,1742,69],{}," D — The second test is order-dependent and will fail (or pass) unpredictably depending on execution order, because ",[84,1745,1722],{},[64,1747,1748,1750,1751,1753,1754,1757,1758,1760,1761,1764,1765,1462,1767,1769,1770,1773,1774,1777,1778,1781,1782,1785],{},[67,1749,75],{}," Test isolation means each test should start from a known, independent state. Here, ",[84,1752,1722],{}," lives outside any test and outside any setup hook, so it accumulates across the whole file: after the first test runs, ",[84,1755,1756],{},"cache.length"," is already ",[84,1759,577],{},", so the second test's ",[84,1762,1763],{},"addItem(\"b\")"," returns ",[84,1766,782],{},[84,1768,577],{},", and the assertion fails — but only if the tests run in that order. If a test runner or ",[84,1771,1772],{},"--shuffle"," flag reorders tests, or a test is run in isolation with ",[84,1775,1776],{},".only",", the outcome flips unpredictably. The fix is to reset ",[84,1779,1780],{},"cache = []"," in a ",[84,1783,1784],{},"beforeEach",", or avoid module-level mutable state entirely by scoping it inside each test. Option A describes behavior no mainstream test runner provides by default — module state persists across tests in the same file unless explicitly reset.",[14,1787,1788,1799,1944,2005],{"language":16},[18,1789,1791,1792,1794,1795,1798],{"id":1790},"q12-what-do-beforeeach-and-aftereach-accomplish-in-this-test-file","Q12. What do ",[84,1793,1784],{}," and ",[84,1796,1797],{},"afterEach"," accomplish in this test file?",[109,1800,1801],{"language":16},[112,1802,1804],{"className":114,"code":1803,"language":16,"meta":116,"style":116},"describe(\"UserRepository\", () => {\n  let repo;\n\n  beforeEach(() => {\n    repo = new UserRepository();\n  });\n\n  afterEach(() => {\n    repo.close();\n  });\n\n  test(\"starts empty\", () => {\n    expect(repo.count()).toBe(0);\n  });\n});\n",[84,1805,1806,1822,1830,1834,1846,1860,1864,1868,1879,1889,1893,1897,1913,1935,1939],{"__ignoreMap":116},[120,1807,1808,1811,1813,1816,1818,1820],{"class":122,"line":123},[120,1809,1810],{"class":126},"describe",[120,1812,131],{"class":130},[120,1814,1815],{"class":134},"\"UserRepository\"",[120,1817,563],{"class":130},[120,1819,148],{"class":141},[120,1821,151],{"class":130},[120,1823,1824,1827],{"class":122,"line":154},[120,1825,1826],{"class":141},"  let",[120,1828,1829],{"class":130}," repo;\n",[120,1831,1832],{"class":122,"line":188},[120,1833,215],{"emptyLinePlaceholder":35},[120,1835,1836,1839,1842,1844],{"class":122,"line":212},[120,1837,1838],{"class":126},"  beforeEach",[120,1840,1841],{"class":130},"(() ",[120,1843,148],{"class":141},[120,1845,151],{"class":130},[120,1847,1848,1851,1853,1855,1858],{"class":122,"line":218},[120,1849,1850],{"class":130},"    repo ",[120,1852,1387],{"class":141},[120,1854,167],{"class":141},[120,1856,1857],{"class":126}," UserRepository",[120,1859,445],{"class":130},[120,1861,1862],{"class":122,"line":237},[120,1863,619],{"class":130},[120,1865,1866],{"class":122,"line":242},[120,1867,215],{"emptyLinePlaceholder":35},[120,1869,1870,1873,1875,1877],{"class":122,"line":261},[120,1871,1872],{"class":126},"  afterEach",[120,1874,1841],{"class":130},[120,1876,148],{"class":141},[120,1878,151],{"class":130},[120,1880,1881,1884,1887],{"class":122,"line":1615},[120,1882,1883],{"class":130},"    repo.",[120,1885,1886],{"class":126},"close",[120,1888,445],{"class":130},[120,1890,1891],{"class":122,"line":1641},[120,1892,619],{"class":130},[120,1894,1895],{"class":122,"line":1646},[120,1896,215],{"emptyLinePlaceholder":35},[120,1898,1899,1902,1904,1907,1909,1911],{"class":122,"line":1651},[120,1900,1901],{"class":126},"  test",[120,1903,131],{"class":130},[120,1905,1906],{"class":134},"\"starts empty\"",[120,1908,563],{"class":130},[120,1910,148],{"class":141},[120,1912,151],{"class":130},[120,1914,1915,1917,1920,1923,1926,1928,1930,1933],{"class":122,"line":1667},[120,1916,602],{"class":126},[120,1918,1919],{"class":130},"(repo.",[120,1921,1922],{"class":126},"count",[120,1924,1925],{"class":130},"()).",[120,1927,251],{"class":126},[120,1929,131],{"class":130},[120,1931,1932],{"class":160},"0",[120,1934,258],{"class":130},[120,1936,1937],{"class":122,"line":1691},[120,1938,619],{"class":130},[120,1940,1942],{"class":122,"line":1941},15,[120,1943,264],{"class":130},[23,1945,1947,1960,1975,1989],{"className":1946},[26],[28,1948,1950,369,1952,377,1954,1956,1957,1959],{"className":1949},[31],[33,1951],{"disabled":35,"type":36},[84,1953,1784],{},[84,1955,1797],{}," run once total for the whole ",[84,1958,1810],{}," block, before\u002Fafter all its tests combined",[28,1961,1963,369,1965,1967,1968,1970,1971,1974],{"className":1962},[31],[33,1964],{"disabled":35,"type":36},[84,1966,1797],{}," runs before ",[84,1969,1784],{}," on every test, so ",[84,1972,1973],{},"repo"," is closed before it's even created",[28,1976,1978,369,1980,1982,1983,1985,1986,1988],{"className":1977},[31],[33,1979],{"disabled":35,"type":36},[84,1981,1784],{}," creates a fresh ",[84,1984,1973],{}," before every test in the block and ",[84,1987,1797],{}," tears it down after every test, giving each test an isolated, known starting state instead of leaking state between tests",[28,1990,1992,1994,1995,1997,1998,2000,2001,2004],{"className":1991},[31],[33,1993],{"disabled":35,"type":36}," Because ",[84,1996,1973],{}," is declared with ",[84,1999,1538],{}," outside the hooks, every test shares the exact same ",[84,2002,2003],{},"UserRepository"," instance",[57,2006,2007,2009,2020],{},[60,2008,62],{},[64,2010,2011,2013,2014,1982,2016,1985,2018,1988],{},[67,2012,69],{}," C — ",[84,2015,1784],{},[84,2017,1973],{},[84,2019,1797],{},[64,2021,2022,369,2024,377,2026,2028,2029,369,2032,377,2034,2037,2038,2040,2041,377,2044,2047,2048,2050,2051,2053,2054,369,2056,369,2059,2061],{},[67,2023,75],{},[84,2025,1784],{},[84,2027,1797],{}," run around ",[717,2030,2031],{},"every individual",[84,2033,127],{},[84,2035,2036],{},"it"," in their scope, not once for the whole ",[84,2039,1810],{}," block — that's what ",[84,2042,2043],{},"beforeAll",[84,2045,2046],{},"afterAll"," do instead, which is the mistake option A describes. Each test therefore gets a brand-new ",[84,2049,2003],{}," assigned to the shared ",[84,2052,1973],{}," variable, and the previous instance is closed afterward, preventing the kind of cross-test state leakage seen in Q11. Option B reverses the actual execution order — setup always runs before the test, teardown after. Option D is wrong precisely because ",[84,2055,1784],{},[717,2057,2058],{},"reassigns",[84,2060,1973],{}," to a new instance before each test, so the reference changes even though the variable binding itself is declared once.",[14,2063,2064,2083,2213,2293],{"language":16},[18,2065,2067,2068,2071,2072,2074,2075,2078,2079,2082],{"id":2066},"q13-save-is-a-mock-with-a-canned-return-value-the-first-test-passes-the-second-fails-because-save-has-already-been-called-once-by-the-time-it-runs-which-fix-resets-the-call-count-between-tests-without-discarding-the-mockreturnvaluetrue-behavior","Q13. ",[84,2069,2070],{},"save"," is a mock with a canned return value. The first test passes; the second fails because ",[84,2073,2070],{}," has already been called once by the time it runs. Which fix resets the call count between tests ",[717,2076,2077],{},"without"," discarding the ",[84,2080,2081],{},"mockReturnValue(true)"," behavior?",[109,2084,2085],{"language":16},[112,2086,2088],{"className":114,"code":2087,"language":16,"meta":116,"style":116},"const save = jest.fn().mockReturnValue(true);\n\ntest(\"first call\", () => {\n  save(\"a\");\n  expect(save).toHaveBeenCalledTimes(1);\n});\n\ntest(\"second call\", () => {\n  save(\"b\");\n  expect(save).toHaveBeenCalledTimes(1);\n});\n",[84,2089,2090,2116,2120,2135,2146,2162,2166,2170,2185,2195,2209],{"__ignoreMap":116},[120,2091,2092,2094,2097,2099,2101,2104,2107,2110,2112,2114],{"class":122,"line":123},[120,2093,414],{"class":141},[120,2095,2096],{"class":160}," save",[120,2098,164],{"class":141},[120,2100,422],{"class":130},[120,2102,2103],{"class":126},"fn",[120,2105,2106],{"class":130},"().",[120,2108,2109],{"class":126},"mockReturnValue",[120,2111,131],{"class":130},[120,2113,206],{"class":160},[120,2115,258],{"class":130},[120,2117,2118],{"class":122,"line":154},[120,2119,215],{"emptyLinePlaceholder":35},[120,2121,2122,2124,2126,2129,2131,2133],{"class":122,"line":188},[120,2123,127],{"class":126},[120,2125,131],{"class":130},[120,2127,2128],{"class":134},"\"first call\"",[120,2130,563],{"class":130},[120,2132,148],{"class":141},[120,2134,151],{"class":130},[120,2136,2137,2140,2142,2144],{"class":122,"line":212},[120,2138,2139],{"class":126},"  save",[120,2141,131],{"class":130},[120,2143,1627],{"class":134},[120,2145,258],{"class":130},[120,2147,2148,2150,2153,2156,2158,2160],{"class":122,"line":218},[120,2149,245],{"class":126},[120,2151,2152],{"class":130},"(save).",[120,2154,2155],{"class":126},"toHaveBeenCalledTimes",[120,2157,131],{"class":130},[120,2159,577],{"class":160},[120,2161,258],{"class":130},[120,2163,2164],{"class":122,"line":237},[120,2165,264],{"class":130},[120,2167,2168],{"class":122,"line":242},[120,2169,215],{"emptyLinePlaceholder":35},[120,2171,2172,2174,2176,2179,2181,2183],{"class":122,"line":261},[120,2173,127],{"class":126},[120,2175,131],{"class":130},[120,2177,2178],{"class":134},"\"second call\"",[120,2180,563],{"class":130},[120,2182,148],{"class":141},[120,2184,151],{"class":130},[120,2186,2187,2189,2191,2193],{"class":122,"line":1615},[120,2188,2139],{"class":126},[120,2190,131],{"class":130},[120,2192,1678],{"class":134},[120,2194,258],{"class":130},[120,2196,2197,2199,2201,2203,2205,2207],{"class":122,"line":1641},[120,2198,245],{"class":126},[120,2200,2152],{"class":130},[120,2202,2155],{"class":126},[120,2204,131],{"class":130},[120,2206,577],{"class":160},[120,2208,258],{"class":130},[120,2210,2211],{"class":122,"line":1646},[120,2212,264],{"class":130},[23,2214,2216,2237,2258,2287],{"className":2215},[26],[28,2217,2219,2221,2222,2225,2226,2228,2229,2231,2232,2234,2235],{"className":2218},[31],[33,2220],{"disabled":35,"type":36}," Add ",[84,2223,2224],{},"jest.restoreAllMocks()"," in an ",[84,2227,1797],{}," — it only affects mocks created with ",[84,2230,482],{},", restoring their original (non-mocked) implementation, so it wouldn't touch a plain ",[84,2233,376],{}," like ",[84,2236,2070],{},[28,2238,2240,2221,2242,2225,2245,2247,2248,377,2251,2254,2255,2257],{"className":2239},[31],[33,2241],{"disabled":35,"type":36},[84,2243,2244],{},"jest.clearAllMocks()",[84,2246,1797],{}," — it resets ",[84,2249,2250],{},"mock.calls",[84,2252,2253],{},"mock.instances"," (so the recorded call count starts fresh before each test) but leaves the configured ",[84,2256,2081],{}," implementation intact",[28,2259,2261,2221,2263,2225,2266,2268,2269,377,2271,2274,2275,2277,2278,2280,2281,2284,2285],{"className":2260},[31],[33,2262],{"disabled":35,"type":36},[84,2264,2265],{},"jest.resetAllMocks()",[84,2267,1797],{}," — it clears call history AND removes any configured ",[84,2270,2109],{},[84,2272,2273],{},"mockImplementation",", resetting ",[84,2276,2070],{}," to a plain mock that returns ",[84,2279,652],{},", so ",[84,2282,2283],{},"save(\"b\")"," would no longer return ",[84,2286,206],{},[28,2288,2290,2292],{"className":2289},[31],[33,2291],{"disabled":35,"type":36}," Do nothing — the test runner automatically clears mock call counts between tests by default in every configuration",[57,2294,2295,2297,2312],{},[60,2296,62],{},[64,2298,2299,2301,2302,2225,2304,2247,2306,377,2308,2254,2310,2257],{},[67,2300,69],{}," B — Add ",[84,2303,2244],{},[84,2305,1797],{},[84,2307,2250],{},[84,2309,2253],{},[84,2311,2081],{},[64,2313,2314,369,2316,369,2318,2321,2322,2324,2325,377,2328,2330,2331,2333,2334,2336,2337,2339,2340,377,2343,2345,2346,2349,2350,2352,2353,2355,2356,377,2359,377,2362,2365,2366,377,2369,377,2372,2375],{},[67,2315,75],{},[67,2317,372],{},[84,2319,2320],{},"mockClear()"," (and its bulk form ",[84,2323,2244],{},") only wipes recorded call history — arguments, call count, results — leaving any configured implementation untouched, which is exactly what's needed here. ",[84,2326,2327],{},"mockReset()",[84,2329,2265],{}," goes further and also strips the mocked implementation, which is why option C's ",[84,2332,2070],{}," would start returning ",[84,2335,652],{},", breaking any test relying on ",[84,2338,206],{},". ",[84,2341,2342],{},"mockRestore()",[84,2344,2224],{}," goes furthest, restoring the ",[717,2347,2348],{},"original"," un-mocked implementation, but that only applies to mocks created via ",[84,2351,482],{}," on a real method — a bare ",[84,2354,376],{}," has no \"original\" to restore to, so option A wouldn't fix anything. (",[84,2357,2358],{},"clearAllMocks",[84,2360,2361],{},"resetAllMocks",[84,2363,2364],{},"restoreAllMocks"," are Jest's specific method names; Vitest mirrors them as ",[84,2367,2368],{},"vi.clearAllMocks()",[84,2370,2371],{},"vi.resetAllMocks()",[84,2373,2374],{},"vi.restoreAllMocks()"," — the underlying three-tier distinction is the part worth remembering.) Option D is false; leftover mock state across tests is a common, real cause of flakiness, not something runners fix automatically.",[14,2377,2378,2382,2512,2568],{"language":16},[18,2379,2381],{"id":2380},"q14-why-does-this-test-complete-instantly-instead-of-taking-5-real-seconds","Q14. Why does this test complete instantly instead of taking 5 real seconds?",[109,2383,2384],{"language":16},[112,2385,2387],{"className":114,"code":2386,"language":16,"meta":116,"style":116},"function scheduleReminder(cb) {\n  setTimeout(cb, 5000);\n}\n\ntest(\"calls the callback after 5 seconds\", () => {\n  jest.useFakeTimers();\n  const cb = jest.fn();\n  scheduleReminder(cb);\n\n  jest.advanceTimersByTime(5000);\n\n  expect(cb).toHaveBeenCalledTimes(1);\n});\n",[84,2388,2389,2403,2416,2420,2424,2439,2449,2464,2472,2476,2489,2493,2508],{"__ignoreMap":116},[120,2390,2391,2393,2396,2398,2401],{"class":122,"line":123},[120,2392,1555],{"class":141},[120,2394,2395],{"class":126}," scheduleReminder",[120,2397,131],{"class":130},[120,2399,2400],{"class":589},"cb",[120,2402,1005],{"class":130},[120,2404,2405,2408,2411,2414],{"class":122,"line":154},[120,2406,2407],{"class":126},"  setTimeout",[120,2409,2410],{"class":130},"(cb, ",[120,2412,2413],{"class":160},"5000",[120,2415,258],{"class":130},[120,2417,2418],{"class":122,"line":188},[120,2419,1055],{"class":130},[120,2421,2422],{"class":122,"line":212},[120,2423,215],{"emptyLinePlaceholder":35},[120,2425,2426,2428,2430,2433,2435,2437],{"class":122,"line":218},[120,2427,127],{"class":126},[120,2429,131],{"class":130},[120,2431,2432],{"class":134},"\"calls the callback after 5 seconds\"",[120,2434,563],{"class":130},[120,2436,148],{"class":141},[120,2438,151],{"class":130},[120,2440,2441,2444,2447],{"class":122,"line":237},[120,2442,2443],{"class":130},"  jest.",[120,2445,2446],{"class":126},"useFakeTimers",[120,2448,445],{"class":130},[120,2450,2451,2453,2456,2458,2460,2462],{"class":122,"line":242},[120,2452,157],{"class":141},[120,2454,2455],{"class":160}," cb",[120,2457,164],{"class":141},[120,2459,422],{"class":130},[120,2461,2103],{"class":126},[120,2463,445],{"class":130},[120,2465,2466,2469],{"class":122,"line":261},[120,2467,2468],{"class":126},"  scheduleReminder",[120,2470,2471],{"class":130},"(cb);\n",[120,2473,2474],{"class":122,"line":1615},[120,2475,215],{"emptyLinePlaceholder":35},[120,2477,2478,2480,2483,2485,2487],{"class":122,"line":1641},[120,2479,2443],{"class":130},[120,2481,2482],{"class":126},"advanceTimersByTime",[120,2484,131],{"class":130},[120,2486,2413],{"class":160},[120,2488,258],{"class":130},[120,2490,2491],{"class":122,"line":1646},[120,2492,215],{"emptyLinePlaceholder":35},[120,2494,2495,2497,2500,2502,2504,2506],{"class":122,"line":1651},[120,2496,245],{"class":126},[120,2498,2499],{"class":130},"(cb).",[120,2501,2155],{"class":126},[120,2503,131],{"class":130},[120,2505,577],{"class":160},[120,2507,258],{"class":130},[120,2509,2510],{"class":122,"line":1667},[120,2511,264],{"class":130},[23,2513,2515,2528,2543,2559],{"className":2514},[26],[28,2516,2518,369,2520,2523,2524,2527],{"className":2517},[31],[33,2519],{"disabled":35,"type":36},[84,2521,2522],{},"jest.useFakeTimers()"," replaces the global timer functions with mock versions; ",[84,2525,2526],{},"jest.advanceTimersByTime(5000)"," then synchronously fast-forwards the mocked clock and fires any callbacks scheduled at or before that point — no real waiting occurs, so the test runs instantly",[28,2529,2531,2533,2534,2536,2537,1462,2540],{"className":2530},[31],[33,2532],{"disabled":35,"type":36}," This test actually waits 5 real seconds; ",[84,2535,2482],{}," only affects ",[84,2538,2539],{},"Date.now()",[84,2541,2542],{},"setTimeout",[28,2544,2546,369,2548,2550,2551,1462,2554,2280,2556,2558],{"className":2545},[31],[33,2547],{"disabled":35,"type":36},[84,2549,2522],{}," only works with ",[84,2552,2553],{},"setInterval",[84,2555,2542],{},[84,2557,2400],{}," is never called",[28,2560,2562,369,2564,2567],{"className":2561},[31],[33,2563],{"disabled":35,"type":36},[84,2565,2566],{},"advanceTimersByTime(5000)"," schedules the callback to run 5000 real milliseconds from now, instead of running it immediately",[57,2569,2570,2572,2580],{},[60,2571,62],{},[64,2573,2574,932,2576,2523,2578,2527],{},[67,2575,69],{},[84,2577,2522],{},[84,2579,2526],{},[64,2581,2582,2584,2585,377,2587,377,2589,2592,2593,2596,2597,2600,2601,2603,2604,2607,2608,1794,2610,2612],{},[67,2583,75],{}," Fake timers swap out ",[84,2586,2542],{},[84,2588,2553],{},[84,2590,2591],{},"Date"," (depending on configuration) with mock implementations that track scheduled callbacks against a fake internal clock instead of the real system clock. ",[84,2594,2595],{},"advanceTimersByTime(ms)"," moves that fake clock forward by ",[84,2598,2599],{},"ms"," and synchronously invokes any callbacks whose delay has now elapsed, letting time-based code be tested in milliseconds of real wall-clock time instead of actually waiting. (",[84,2602,2522],{}," is Jest's API name; Vitest's equivalent is ",[84,2605,2606],{},"vi.useFakeTimers()"," — the fake-clock concept itself is universal.) Options B and C misdescribe what fake timers intercept — they replace the timer functions themselves, working for both ",[84,2609,2542],{},[84,2611,2553],{},". Option D inverts what \"advance\" means; it moves the clock forward through the scheduled point, not away from it.",[14,2614,2615,2624,2787,2847],{"language":16},[18,2616,2618,2619,377,2621,2623],{"id":2617},"q15-this-test-combines-fake-timers-with-a-real-asyncawait-chain-what-subtlety-can-trip-it-up","Q15. This test combines fake timers with a real ",[84,2620,142],{},[84,2622,892],{}," chain. What subtlety can trip it up?",[109,2625,2626],{"language":16},[112,2627,2629],{"className":114,"code":2628,"language":16,"meta":116,"style":116},"async function delayedFetch(id) {\n  await new Promise((resolve) => setTimeout(resolve, 1000));\n  return fetch(`\u002Fusers\u002F${id}`);\n}\n\ntest(\"resolves after the delay\", async () => {\n  jest.useFakeTimers();\n  const promise = delayedFetch(1);\n\n  jest.advanceTimersByTime(1000);\n\n  await expect(promise).resolves.toBeDefined();\n});\n",[84,2630,2631,2646,2677,2696,2700,2704,2723,2731,2748,2752,2764,2768,2783],{"__ignoreMap":116},[120,2632,2633,2635,2637,2640,2642,2644],{"class":122,"line":123},[120,2634,142],{"class":141},[120,2636,994],{"class":141},[120,2638,2639],{"class":126}," delayedFetch",[120,2641,131],{"class":130},[120,2643,812],{"class":589},[120,2645,1005],{"class":130},[120,2647,2648,2651,2653,2656,2658,2661,2663,2665,2668,2671,2674],{"class":122,"line":154},[120,2649,2650],{"class":141},"  await",[120,2652,167],{"class":141},[120,2654,2655],{"class":160}," Promise",[120,2657,586],{"class":130},[120,2659,2660],{"class":589},"resolve",[120,2662,593],{"class":130},[120,2664,148],{"class":141},[120,2666,2667],{"class":126}," setTimeout",[120,2669,2670],{"class":130},"(resolve, ",[120,2672,2673],{"class":160},"1000",[120,2675,2676],{"class":130},"));\n",[120,2678,2679,2681,2684,2686,2689,2691,2694],{"class":122,"line":188},[120,2680,1041],{"class":141},[120,2682,2683],{"class":126}," fetch",[120,2685,131],{"class":130},[120,2687,2688],{"class":134},"`\u002Fusers\u002F${",[120,2690,812],{"class":130},[120,2692,2693],{"class":134},"}`",[120,2695,258],{"class":130},[120,2697,2698],{"class":122,"line":212},[120,2699,1055],{"class":130},[120,2701,2702],{"class":122,"line":218},[120,2703,215],{"emptyLinePlaceholder":35},[120,2705,2706,2708,2710,2713,2715,2717,2719,2721],{"class":122,"line":237},[120,2707,127],{"class":126},[120,2709,131],{"class":130},[120,2711,2712],{"class":134},"\"resolves after the delay\"",[120,2714,138],{"class":130},[120,2716,142],{"class":141},[120,2718,145],{"class":130},[120,2720,148],{"class":141},[120,2722,151],{"class":130},[120,2724,2725,2727,2729],{"class":122,"line":242},[120,2726,2443],{"class":130},[120,2728,2446],{"class":126},[120,2730,445],{"class":130},[120,2732,2733,2735,2738,2740,2742,2744,2746],{"class":122,"line":261},[120,2734,157],{"class":141},[120,2736,2737],{"class":160}," promise",[120,2739,164],{"class":141},[120,2741,2639],{"class":126},[120,2743,131],{"class":130},[120,2745,577],{"class":160},[120,2747,258],{"class":130},[120,2749,2750],{"class":122,"line":1615},[120,2751,215],{"emptyLinePlaceholder":35},[120,2753,2754,2756,2758,2760,2762],{"class":122,"line":1641},[120,2755,2443],{"class":130},[120,2757,2482],{"class":126},[120,2759,131],{"class":130},[120,2761,2673],{"class":160},[120,2763,258],{"class":130},[120,2765,2766],{"class":122,"line":1646},[120,2767,215],{"emptyLinePlaceholder":35},[120,2769,2770,2772,2775,2778,2781],{"class":122,"line":1651},[120,2771,2650],{"class":141},[120,2773,2774],{"class":126}," expect",[120,2776,2777],{"class":130},"(promise).resolves.",[120,2779,2780],{"class":126},"toBeDefined",[120,2782,445],{"class":130},[120,2784,2785],{"class":122,"line":1667},[120,2786,264],{"class":130},[23,2788,2790,2799,2815,2831],{"className":2789},[26],[28,2791,2793,2795,2796,2798],{"className":2792},[31],[33,2794],{"disabled":35,"type":36}," This is completely safe — ",[84,2797,2482],{}," always resolves every pending promise in the same synchronous call, so no extra step is ever needed",[28,2800,2802,369,2804,2806,2807,377,2809,2811,2812],{"className":2801},[31],[33,2803],{"disabled":35,"type":36},[84,2805,2522],{}," disables ",[84,2808,142],{},[84,2810,892],{}," entirely, so this test throws a ",[84,2813,2814],{},"SyntaxError",[28,2816,2818,369,2820,2823,2824,2826,2827,2830],{"className":2817},[31],[33,2819],{"disabled":35,"type":36},[84,2821,2822],{},"fetch"," cannot be called inside a function that uses ",[84,2825,2542],{},", so this test always throws a ",[84,2828,2829],{},"ReferenceError"," regardless of timers",[28,2832,2834,2836,2837,886,2839,2842,2843,2846],{"className":2833},[31],[33,2835],{"disabled":35,"type":36}," Advancing fake timers fires the timer callback synchronously, but resuming the ",[84,2838,892],{},[84,2840,2841],{},"delayedFetch"," still requires a separate microtask tick — advancing timers doesn't automatically flush pending microtasks from real Promises, so mixing fake timers with async code can need an extra ",[84,2844,2845],{},"await Promise.resolve()"," (or an async-aware timer-advance helper) before the promise actually settles",[57,2848,2849,2851,2862],{},[60,2850,62],{},[64,2852,2853,2855,2856,886,2858,2842,2860,2846],{},[67,2854,69],{}," D — Advancing fake timers fires the timer callback synchronously, but resuming the ",[84,2857,892],{},[84,2859,2841],{},[84,2861,2845],{},[64,2863,2864,369,2866,369,2868,2870,2871,2873,2874,2877,2878,2880,2881,2884,2885,2888,2889,2892,2893,377,2896,2899],{},[67,2865,75],{},[67,2867,519],{},[84,2869,2482],{}," operates on the macrotask\u002Ftimer queue — it synchronously invokes the ",[84,2872,2542],{}," callback (which calls ",[84,2875,2876],{},"resolve()","), but resuming execution after an ",[84,2879,892],{}," happens on the microtask queue, on the next tick. If the mock-timer implementation doesn't also flush pending microtasks, the outer ",[84,2882,2883],{},"await expect(promise).resolves..."," can end up racing the still-pending microtask, leading to flaky or hanging assertions in some setups. Modern Jest\u002FVitest offer async-aware helpers (e.g. ",[84,2886,2887],{},"jest.advanceTimersByTimeAsync"," \u002F ",[84,2890,2891],{},"vi.advanceTimersByTimeAsync",", or awaiting a ",[84,2894,2895],{},"Promise.resolve()",[84,2897,2898],{},"flushPromises()"," tick) specifically to bridge this gap. Options B and C describe failures that don't occur — fake timers don't disable async\u002Fawait or forbid calling other functions inside a timer-based one; option A overstates the guarantee and is the assumption that causes real intermittent failures in test suites mixing fake timers with real promise chains.",[14,2901,2902,2906,3023,3078],{"language":16},[18,2903,2905],{"id":2904},"q16-what-is-wrong-with-testing-this-function-by-asserting-on-a-hardcoded-expected-output","Q16. What is wrong with testing this function by asserting on a hardcoded expected output?",[109,2907,2908],{"language":16},[112,2909,2911],{"className":114,"code":2910,"language":16,"meta":116,"style":116},"function generateOrderId() {\n  return `ORD-${Date.now()}-${Math.floor(Math.random() * 1000)}`;\n}\n\ntest(\"generateOrderId returns a predictable id\", () => {\n  expect(generateOrderId()).toBe(\"ORD-1700000000000-42\");\n});\n",[84,2912,2913,2923,2976,2980,2984,2999,3019],{"__ignoreMap":116},[120,2914,2915,2917,2920],{"class":122,"line":123},[120,2916,1555],{"class":141},[120,2918,2919],{"class":126}," generateOrderId",[120,2921,2922],{"class":130},"() {\n",[120,2924,2925,2927,2930,2932,2934,2937,2940,2943,2946,2948,2951,2953,2955,2957,2960,2963,2966,2969,2972,2974],{"class":122,"line":154},[120,2926,1041],{"class":141},[120,2928,2929],{"class":134}," `ORD-${",[120,2931,2591],{"class":130},[120,2933,731],{"class":134},[120,2935,2936],{"class":126},"now",[120,2938,2939],{"class":134},"()",[120,2941,2942],{"class":134},"}-${",[120,2944,2945],{"class":130},"Math",[120,2947,731],{"class":134},[120,2949,2950],{"class":126},"floor",[120,2952,131],{"class":134},[120,2954,2945],{"class":130},[120,2956,731],{"class":134},[120,2958,2959],{"class":126},"random",[120,2961,2962],{"class":134},"() ",[120,2964,2965],{"class":141},"*",[120,2967,2968],{"class":160}," 1000",[120,2970,2971],{"class":134},")",[120,2973,2693],{"class":134},[120,2975,1589],{"class":130},[120,2977,2978],{"class":122,"line":188},[120,2979,1055],{"class":130},[120,2981,2982],{"class":122,"line":212},[120,2983,215],{"emptyLinePlaceholder":35},[120,2985,2986,2988,2990,2993,2995,2997],{"class":122,"line":218},[120,2987,127],{"class":126},[120,2989,131],{"class":130},[120,2991,2992],{"class":134},"\"generateOrderId returns a predictable id\"",[120,2994,563],{"class":130},[120,2996,148],{"class":141},[120,2998,151],{"class":130},[120,3000,3001,3003,3005,3008,3010,3012,3014,3017],{"class":122,"line":237},[120,3002,245],{"class":126},[120,3004,131],{"class":130},[120,3006,3007],{"class":126},"generateOrderId",[120,3009,1925],{"class":130},[120,3011,251],{"class":126},[120,3013,131],{"class":130},[120,3015,3016],{"class":134},"\"ORD-1700000000000-42\"",[120,3018,258],{"class":130},[120,3020,3021],{"class":122,"line":242},[120,3022,264],{"class":130},[23,3024,3026,3039,3050,3069],{"className":3025},[26],[28,3027,3029,3031,3032,3034,3035,3038],{"className":3028},[31],[33,3030],{"disabled":35,"type":36}," This test is fine, because the test runner automatically freezes ",[84,3033,2539],{}," and seeds ",[84,3036,3037],{},"Math.random()"," for every test run",[28,3040,3042,369,3044,3046,3047,3049],{"className":3041},[31],[33,3043],{"disabled":35,"type":36},[84,3045,3037],{}," always returns the same value within a single test file, so only ",[84,3048,2539],{}," needs mocking",[28,3051,3053,3055,3056,1794,3058,3060,3061,3064,3065,3068],{"className":3052},[31],[33,3054],{"disabled":35,"type":36}," This test is inherently flaky, because ",[84,3057,2539],{},[84,3059,3037],{}," produce different real values on every run; to make it deterministic you need to mock them (e.g. ",[84,3062,3063],{},"jest.spyOn(Date, \"now\").mockReturnValue(...)"," and mock ",[84,3066,3067],{},"Math.random",") or inject a clock\u002FRNG dependency so the test controls their output",[28,3070,3072,3074,3075,3077],{"className":3071},[31],[33,3073],{"disabled":35,"type":36}," This will pass consistently as long as the test runs on the same machine, because ",[84,3076,2539],{}," is deterministic per machine",[57,3079,3080,3082,3095],{},[60,3081,62],{},[64,3083,3084,3086,3087,1794,3089,3060,3091,3064,3093,3068],{},[67,3085,69],{}," C — This test is inherently flaky, because ",[84,3088,2539],{},[84,3090,3037],{},[84,3092,3063],{},[84,3094,3067],{},[64,3096,3097,3099,3100,138,3103,3106],{},[67,3098,75],{}," Any function whose output depends on wall-clock time or randomness cannot be asserted against a fixed literal — the exact same code will produce a different string on every single run, so this test is guaranteed to fail almost immediately after being written (or on any machine other than the one that generated the literal). The fix is either to mock the nondeterministic sources directly (",[84,3101,3102],{},"jest.spyOn(Date, \"now\").mockReturnValue(1700000000000)",[84,3104,3105],{},"jest.spyOn(Math, \"random\").mockReturnValue(0.042)","), or better, to inject a clock and RNG as parameters\u002Fdependencies so the test can supply deterministic fakes without needing to patch globals. Options A, B, and D each invent a guarantee that doesn't exist in JavaScript or any mainstream test runner.",[14,3108,3109,3113,3140],{},[18,3110,3112],{"id":3111},"q17-a-function-under-test-has-five-collaborators-and-the-test-mocks-all-five-then-asserts-only-that-each-mock-was-called-with-the-expected-arguments-in-the-expected-order-what-risk-does-this-pattern-introduce","Q17. A function under test has five collaborators, and the test mocks all five, then asserts only that each mock was called with the expected arguments in the expected order. What risk does this pattern introduce?",[23,3114,3116,3122,3128,3134],{"className":3115},[26],[28,3117,3119,3121],{"className":3118},[31],[33,3120],{"disabled":35,"type":36}," Mocking more dependencies always makes a test suite more reliable, since fewer real code paths can fail",[28,3123,3125,3127],{"className":3124},[31],[33,3126],{"disabled":35,"type":36}," Mocking so many of a function's collaborators that the test only verifies the mocks were called in the expected sequence — rather than exercising any real logic — can create false confidence: the test passes even if the real integration between those pieces is broken, because none of the real code paths actually ran",[28,3129,3131,3133],{"className":3130},[31],[33,3132],{"disabled":35,"type":36}," Over-mocking is only a concern in end-to-end tests, never in unit tests",[28,3135,3137,3139],{"className":3136},[31],[33,3138],{"disabled":35,"type":36}," A test with heavy mocking runs slower than one with no mocks, because mock setup always requires real I\u002FO",[57,3141,3142,3144,3149],{},[60,3143,62],{},[64,3145,3146,3148],{},[67,3147,69],{}," B — Mocking so many of a function's collaborators that the test only verifies the mocks were called in the expected sequence — rather than exercising any real logic — can create false confidence: the test passes even if the real integration between those pieces is broken, because none of the real code paths actually ran",[64,3150,3151,3153,3154,3157],{},[67,3152,75],{}," When every collaborator is replaced with a mock, the \"system under test\" shrinks down to just the glue code wiring those mocks together — the test proves that glue code calls things in the right order, but proves nothing about whether the real implementations actually work together correctly. This is a genuine, common trap: a suite can be full of green tests like this while a refactor that changes real interaction contracts (argument shapes, error handling) sails through undetected, because nothing in the test exercised real behavior. Option A inverts the actual risk — more mocking generally means less real code is verified, not more reliability. Option C is false; over-mocking is very much a unit-test problem, arguably its most common failure mode. Option D confuses mock setup cost with I\u002FO cost; mocks specifically avoid real I\u002FO and are typically ",[717,3155,3156],{},"faster",", not slower.",[14,3159,3160,3168,3276,3333],{"language":16},[18,3161,3163,3164,3167],{"id":3162},"q18-this-test-achieves-100-line-coverage-of-divide-what-is-still-missing","Q18. This test achieves 100% line coverage of ",[84,3165,3166],{},"divide",". What is still missing?",[109,3169,3170],{"language":16},[112,3171,3173],{"className":114,"code":3172,"language":16,"meta":116,"style":116},"function divide(a, b) {\n  if (b === 0) throw new Error(\"Cannot divide by zero\");\n  return a \u002F b;\n}\n\ntest(\"divide runs without crashing\", () => {\n  divide(10, 2);\n});\n",[84,3174,3175,3194,3221,3233,3237,3241,3256,3272],{"__ignoreMap":116},[120,3176,3177,3179,3182,3184,3187,3189,3192],{"class":122,"line":123},[120,3178,1555],{"class":141},[120,3180,3181],{"class":126}," divide",[120,3183,131],{"class":130},[120,3185,3186],{"class":589},"a",[120,3188,138],{"class":130},[120,3190,3191],{"class":589},"b",[120,3193,1005],{"class":130},[120,3195,3196,3198,3201,3204,3206,3208,3210,3212,3214,3216,3219],{"class":122,"line":154},[120,3197,1010],{"class":141},[120,3199,3200],{"class":130}," (b ",[120,3202,3203],{"class":141},"===",[120,3205,1019],{"class":160},[120,3207,593],{"class":130},[120,3209,1024],{"class":141},[120,3211,167],{"class":141},[120,3213,1029],{"class":126},[120,3215,131],{"class":130},[120,3217,3218],{"class":134},"\"Cannot divide by zero\"",[120,3220,258],{"class":130},[120,3222,3223,3225,3228,3230],{"class":122,"line":188},[120,3224,1041],{"class":141},[120,3226,3227],{"class":130}," a ",[120,3229,377],{"class":141},[120,3231,3232],{"class":130}," b;\n",[120,3234,3235],{"class":122,"line":212},[120,3236,1055],{"class":130},[120,3238,3239],{"class":122,"line":218},[120,3240,215],{"emptyLinePlaceholder":35},[120,3242,3243,3245,3247,3250,3252,3254],{"class":122,"line":237},[120,3244,127],{"class":126},[120,3246,131],{"class":130},[120,3248,3249],{"class":134},"\"divide runs without crashing\"",[120,3251,563],{"class":130},[120,3253,148],{"class":141},[120,3255,151],{"class":130},[120,3257,3258,3261,3263,3266,3268,3270],{"class":122,"line":242},[120,3259,3260],{"class":126},"  divide",[120,3262,131],{"class":130},[120,3264,3265],{"class":160},"10",[120,3267,138],{"class":130},[120,3269,782],{"class":160},[120,3271,258],{"class":130},[120,3273,3274],{"class":122,"line":261},[120,3275,264],{"class":130},[23,3277,3279,3301,3311,3324],{"className":3278},[26],[28,3280,3282,3284,3285,3287,3288,3290,3291,3293,3294,3296,3297,3300],{"className":3281},[31],[33,3283],{"disabled":35,"type":36}," This test can contribute to 100% line coverage for ",[84,3286,3166],{}," while asserting nothing about its behavior — it never checks that the returned value is actually ",[84,3289,1191],{},", so a bug that made ",[84,3292,3166],{}," always return ",[84,3295,1932],{}," (or ",[84,3298,3299],{},"NaN",") would still leave this test green. High coverage measures which lines executed, not whether the output was verified",[28,3302,3304,3306,3307,3310],{"className":3303},[31],[33,3305],{"disabled":35,"type":36}," This test is equivalent to ",[84,3308,3309],{},"expect(divide(10, 2)).toBe(5)",", because the test runner automatically asserts on the return value of the last expression in a test",[28,3312,3314,3316,3317,3319,3320,3323],{"className":3313},[31],[33,3315],{"disabled":35,"type":36}," This test fails automatically, because a ",[84,3318,672],{}," block must contain at least one ",[84,3321,3322],{},"expect()"," call",[28,3325,3327,3329,3330,3332],{"className":3326},[31],[33,3328],{"disabled":35,"type":36}," Line coverage tools report this line as uncovered because no ",[84,3331,3322],{}," was used, so the false sense of confidence described doesn't apply here",[57,3334,3335,3337,3352],{},[60,3336,62],{},[64,3338,3339,3341,3342,3287,3344,3290,3346,3293,3348,3296,3350,3300],{},[67,3340,69],{}," A — This test can contribute to 100% line coverage for ",[84,3343,3166],{},[84,3345,1191],{},[84,3347,3166],{},[84,3349,1932],{},[84,3351,3299],{},[64,3353,3354,3356,3357,3360,3361,3364,3365,3368,3369,3371,3372,3374,3375,3378,3379,3382],{},[67,3355,75],{}," Line\u002Fbranch coverage is purely a measure of which code ",[717,3358,3359],{},"ran"," during the test suite, not whether the test made any meaningful claim about correctness. Calling ",[84,3362,3363],{},"divide(10, 2)"," executes the ",[84,3366,3367],{},"return a \u002F b"," line, satisfying coverage tooling, but with zero ",[84,3370,3322],{}," calls the test can never fail no matter how wrong the computed value is — coverage percentage and correctness confidence are two different axes that can diverge sharply. Option B invents a behavior no mainstream test runner has; nothing is asserted automatically. Option C is false — most runners do not require an ",[84,3373,3322],{}," per test by default (some can be configured with ",[84,3376,3377],{},"expect.assertions()"," to enforce it, but that's opt-in, not automatic). Option D is wrong for the reason stated in the correct answer: the line ",[717,3380,3381],{},"does"," count as covered by execution alone, regardless of whether it was asserted on.",[14,3384,3385,3389,3416],{},[18,3386,3388],{"id":3387},"q19-a-test-suite-occasionally-fails-because-a-test-makes-a-real-http-call-to-a-third-party-api-which-is-sometimes-slow-or-briefly-unavailable-what-is-the-best-practice-fix","Q19. A test suite occasionally fails because a test makes a real HTTP call to a third-party API, which is sometimes slow or briefly unavailable. What is the best-practice fix?",[23,3390,3392,3398,3404,3410],{"className":3391},[26],[28,3393,3395,3397],{"className":3394},[31],[33,3396],{"disabled":35,"type":36}," Add a retry mechanism so the test simply reruns until it passes",[28,3399,3401,3403],{"className":3400},[31],[33,3402],{"disabled":35,"type":36}," Keep the real network call, since network-dependent tests are considered best practice — they prove the code works against the real production API",[28,3405,3407,3409],{"className":3406},[31],[33,3408],{"disabled":35,"type":36}," Increase the test timeout, since that addresses the root cause of network-related flakiness",[28,3411,3413,3415],{"className":3412},[31],[33,3414],{"disabled":35,"type":36}," A test that calls a real external API introduces flakiness from network latency, rate limits, and outages that have nothing to do with whether the code under test is correct; the best practice is to isolate the unit by mocking the network layer (or using a recorded fixture\u002Ffake server) so the test's pass\u002Ffail depends only on the code being tested",[57,3417,3418,3420,3425],{},[60,3419,62],{},[64,3421,3422,3424],{},[67,3423,69],{}," D — A test that calls a real external API introduces flakiness from network latency, rate limits, and outages that have nothing to do with whether the code under test is correct; the best practice is to isolate the unit by mocking the network layer (or using a recorded fixture\u002Ffake server) so the test's pass\u002Ffail depends only on the code being tested",[64,3426,3427,3429],{},[67,3428,75],{}," A test's job is to give a reliable, repeatable signal about the code under test; anything that ties its outcome to an external system's availability, latency, or rate limits undermines that signal, because the test can now fail for reasons that have nothing to do with a real bug. The standard fix is to isolate the unit from the network entirely — mocking the HTTP client, stubbing the fetch call, or replaying a recorded fixture — so the test exercises the code's logic deterministically, with a separate (typically smaller, explicitly-labeled) suite of true integration\u002FE2E tests reserved for verifying the real network integration occasionally. Option A papers over the symptom without fixing the underlying nondeterminism, and can hide a real regression behind eventual retries. Option B mistakes an E2E concern for a unit-test virtue — real-API calls belong in a deliberately separate, smaller test tier, not scattered through the main suite. Option C doesn't address rate limits or outright outages, and just makes a slow, flaky test slower.",[14,3431,3432,3448,3645,3685],{"language":16},[18,3433,3435,3436,3439,3440,3443,3444,3447],{"id":3434},"q20-two-tests-check-the-same-increment-behavior-on-a-counter-class-that-uses-a-real-count-private-field-which-approach-is-the-better-practice-and-why","Q20. Two tests check the same ",[84,3437,3438],{},"increment"," behavior on a ",[84,3441,3442],{},"Counter"," class that uses a real ",[84,3445,3446],{},"#count"," private field. Which approach is the better practice, and why?",[109,3449,3450],{"language":16},[112,3451,3453],{"className":114,"code":3452,"language":16,"meta":116,"style":116},"class Counter {\n  #count = 0;\n  increment() {\n    this.#count += 1;\n    return this.#count;\n  }\n}\n\ntest(\"increment increases the count (implementation-coupled)\", () => {\n  const c = new Counter();\n  c.increment();\n  expect(c[\"#count\"]).toBe(1);\n});\n\ntest(\"increment increases the count (behavior-based)\", () => {\n  const c = new Counter();\n  expect(c.increment()).toBe(1);\n});\n",[84,3454,3455,3465,3476,3483,3499,3510,3514,3518,3522,3537,3552,3561,3582,3586,3590,3605,3620,3640],{"__ignoreMap":116},[120,3456,3457,3460,3463],{"class":122,"line":123},[120,3458,3459],{"class":141},"class",[120,3461,3462],{"class":126}," Counter",[120,3464,151],{"class":130},[120,3466,3467,3470,3472,3474],{"class":122,"line":154},[120,3468,3469],{"class":589},"  #count",[120,3471,164],{"class":141},[120,3473,1019],{"class":160},[120,3475,1589],{"class":130},[120,3477,3478,3481],{"class":122,"line":188},[120,3479,3480],{"class":126},"  increment",[120,3482,2922],{"class":130},[120,3484,3485,3488,3491,3494,3497],{"class":122,"line":212},[120,3486,3487],{"class":160},"    this",[120,3489,3490],{"class":130},".#count ",[120,3492,3493],{"class":141},"+=",[120,3495,3496],{"class":160}," 1",[120,3498,1589],{"class":130},[120,3500,3501,3504,3507],{"class":122,"line":218},[120,3502,3503],{"class":141},"    return",[120,3505,3506],{"class":160}," this",[120,3508,3509],{"class":130},".#count;\n",[120,3511,3512],{"class":122,"line":237},[120,3513,1224],{"class":130},[120,3515,3516],{"class":122,"line":242},[120,3517,1055],{"class":130},[120,3519,3520],{"class":122,"line":261},[120,3521,215],{"emptyLinePlaceholder":35},[120,3523,3524,3526,3528,3531,3533,3535],{"class":122,"line":1615},[120,3525,127],{"class":126},[120,3527,131],{"class":130},[120,3529,3530],{"class":134},"\"increment increases the count (implementation-coupled)\"",[120,3532,563],{"class":130},[120,3534,148],{"class":141},[120,3536,151],{"class":130},[120,3538,3539,3541,3544,3546,3548,3550],{"class":122,"line":1641},[120,3540,157],{"class":141},[120,3542,3543],{"class":160}," c",[120,3545,164],{"class":141},[120,3547,167],{"class":141},[120,3549,3462],{"class":126},[120,3551,445],{"class":130},[120,3553,3554,3557,3559],{"class":122,"line":1646},[120,3555,3556],{"class":130},"  c.",[120,3558,3438],{"class":126},[120,3560,445],{"class":130},[120,3562,3563,3565,3568,3571,3574,3576,3578,3580],{"class":122,"line":1651},[120,3564,245],{"class":126},[120,3566,3567],{"class":130},"(c[",[120,3569,3570],{"class":134},"\"#count\"",[120,3572,3573],{"class":130},"]).",[120,3575,251],{"class":126},[120,3577,131],{"class":130},[120,3579,577],{"class":160},[120,3581,258],{"class":130},[120,3583,3584],{"class":122,"line":1667},[120,3585,264],{"class":130},[120,3587,3588],{"class":122,"line":1691},[120,3589,215],{"emptyLinePlaceholder":35},[120,3591,3592,3594,3596,3599,3601,3603],{"class":122,"line":1941},[120,3593,127],{"class":126},[120,3595,131],{"class":130},[120,3597,3598],{"class":134},"\"increment increases the count (behavior-based)\"",[120,3600,563],{"class":130},[120,3602,148],{"class":141},[120,3604,151],{"class":130},[120,3606,3608,3610,3612,3614,3616,3618],{"class":122,"line":3607},16,[120,3609,157],{"class":141},[120,3611,3543],{"class":160},[120,3613,164],{"class":141},[120,3615,167],{"class":141},[120,3617,3462],{"class":126},[120,3619,445],{"class":130},[120,3621,3623,3625,3628,3630,3632,3634,3636,3638],{"class":122,"line":3622},17,[120,3624,245],{"class":126},[120,3626,3627],{"class":130},"(c.",[120,3629,3438],{"class":126},[120,3631,1925],{"class":130},[120,3633,251],{"class":126},[120,3635,131],{"class":130},[120,3637,577],{"class":160},[120,3639,258],{"class":130},[120,3641,3643],{"class":122,"line":3642},18,[120,3644,264],{"class":130},[23,3646,3648,3657,3663,3676],{"className":3647},[26],[28,3649,3651,3653,3654,3656],{"className":3650},[31],[33,3652],{"disabled":35,"type":36}," Both tests are equally good, because they both call ",[84,3655,3322],{}," on the counter's state",[28,3658,3660,3662],{"className":3659},[31],[33,3661],{"disabled":35,"type":36}," The first test is preferred, because it verifies the internal field directly, which is more precise than checking the return value",[28,3664,3666,3668,3669,3671,3672,3675],{"className":3665},[31],[33,3667],{"disabled":35,"type":36}," The second test is the better practice: it asserts on the public, observable output (the return value) that consumers actually depend on, so refactoring ",[84,3670,3442],{},"'s internals won't break it. The first test reaches for a private field by bracket-string key, which doesn't actually work with real ",[84,3673,3674],{},"#","-syntax private fields and couples the test to implementation details that can change independently of behavior",[28,3677,3679,3681,3682,3684],{"className":3678},[31],[33,3680],{"disabled":35,"type":36}," Neither test is valid, because private ",[84,3683,3674],{}," fields cannot be tested at all, even indirectly",[57,3686,3687,3689,3698],{},[60,3688,62],{},[64,3690,3691,3693,3694,3671,3696,3675],{},[67,3692,69],{}," C — The second test is the better practice: it asserts on the public, observable output (the return value) that consumers actually depend on, so refactoring ",[84,3695,3442],{},[84,3697,3674],{},[64,3699,3700,3702,3703,3706,3707,3709,3710,3712,3713,3716,3717,3719,3720,3722],{},[67,3701,75],{}," Good tests verify a contract — given these inputs, what output or observable behavior should result — rather than reaching into how that output is produced internally. The second test does exactly that: it only relies on ",[84,3704,3705],{},"increment()","'s public return value, so if ",[84,3708,3442],{}," is later refactored to store its count differently, the test keeps passing as long as the behavior is unchanged. The first test tries to peek at ",[84,3711,3446],{}," via ",[84,3714,3715],{},"c[\"#count\"]",", which is not how JavaScript's true private class fields (",[84,3718,3674],{},"-prefixed) work at all — they are not accessible via bracket\u002Fstring property access from outside the class, so this line either reads ",[84,3721,652],{}," or throws, depending on engine and strict-mode context, making the test broken independent of the design critique. Even a syntactically-valid version of implementation-coupled testing is still the worse practice, because it makes tests brittle against safe refactors that don't change behavior.",[3724,3725,3726],"style",{},"html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}",{"title":116,"searchDepth":154,"depth":154,"links":3728},[3729,3730,3732,3733,3735,3736,3737,3738,3739,3740,3741,3742,3744,3746,3747,3749,3750,3751,3753,3754],{"id":20,"depth":188,"text":21},{"id":81,"depth":188,"text":3731},"Q2. You have processOrder(cart, paymentGateway), which totals a cart and charges a payment gateway. A test constructs an in-memory InMemoryCart and a FakePaymentGateway, calls processOrder, and asserts the resulting order's status is \"paid\". What kind of test is this?",{"id":327,"depth":188,"text":328},{"id":393,"depth":188,"text":3734},"Q4. jest.spyOn(console, \"error\") is called with no .mockImplementation(...) chained after it. What happens when the spied method is invoked during the test?",{"id":543,"depth":188,"text":544},{"id":736,"depth":188,"text":737},{"id":979,"depth":188,"text":980},{"id":1142,"depth":188,"text":1143},{"id":1337,"depth":188,"text":1338},{"id":1474,"depth":188,"text":1475},{"id":1525,"depth":188,"text":1526},{"id":1790,"depth":188,"text":3743},"Q12. What do beforeEach and afterEach accomplish in this test file?",{"id":2066,"depth":188,"text":3745},"Q13. save is a mock with a canned return value. The first test passes; the second fails because save has already been called once by the time it runs. Which fix resets the call count between tests without discarding the mockReturnValue(true) behavior?",{"id":2380,"depth":188,"text":2381},{"id":2617,"depth":188,"text":3748},"Q15. This test combines fake timers with a real async\u002Fawait chain. What subtlety can trip it up?",{"id":2904,"depth":188,"text":2905},{"id":3111,"depth":188,"text":3112},{"id":3162,"depth":188,"text":3752},"Q18. This test achieves 100% line coverage of divide. What is still missing?",{"id":3387,"depth":188,"text":3388},{"id":3434,"depth":188,"text":3755},"Q20. Two tests check the same increment behavior on a Counter class that uses a real #count private field. Which approach is the better practice, and why?","md",{},"\u002Fjs\u002F25-testing",{"title":5,"description":116},"js\u002F25-testing","Cds1rki2tKGnL20phu-XkinEgkgR9yHVuoLjdTY2DgI",1787335397336]