[{"data":1,"prerenderedAt":270},["ShallowReactive",2],{"term-s\u002Fspy":3,"related-s\u002Fspy":256},{"id":4,"title":5,"acronym":6,"body":7,"category":238,"description":239,"difficulty":240,"extension":241,"letter":242,"meta":243,"navigation":81,"path":244,"related":245,"seo":250,"sitemap":251,"stem":254,"subcategory":6,"__hash__":255},"terms\u002Fterms\u002Fs\u002Fspy.md","Spy",null,{"type":8,"value":9,"toc":232},"minimark",[10,15,19,23,26,30,221,225,228],[11,12,14],"h2",{"id":13},"eli5-the-vibe-check","ELI5 — The Vibe Check",[16,17,18],"p",{},"A spy is like a double agent — it lets the real function still do its job, but secretly records everything: how many times it was called, with what arguments, what it returned. You spy on your own code without changing what it does.",[11,20,22],{"id":21},"real-talk","Real Talk",[16,24,25],{},"A spy wraps a real function and records all calls to it without altering its behavior. You can assert after the fact that the function was called the right number of times, with the right arguments. It's a mock that still calls through to the real implementation.",[11,27,29],{"id":28},"show-me-the-code","Show Me The Code",[31,32,37],"pre",{"className":33,"code":34,"language":35,"meta":36,"style":36},"language-javascript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { vi } from 'vitest';\n\nconst consoleSpy = vi.spyOn(console, 'log');\n\nlogUserAction('click', 'button');\n\nexpect(consoleSpy).toHaveBeenCalledWith('USER_ACTION', 'click', 'button');\nconsoleSpy.mockRestore();\n","javascript","",[38,39,40,76,83,123,128,157,162,205],"code",{"__ignoreMap":36},[41,42,45,49,53,57,60,63,66,70,73],"span",{"class":43,"line":44},"line",1,[41,46,48],{"class":47},"s7zQu","import",[41,50,52],{"class":51},"sMK4o"," {",[41,54,56],{"class":55},"sTEyZ"," vi",[41,58,59],{"class":51}," }",[41,61,62],{"class":47}," from",[41,64,65],{"class":51}," '",[41,67,69],{"class":68},"sfazB","vitest",[41,71,72],{"class":51},"'",[41,74,75],{"class":51},";\n",[41,77,79],{"class":43,"line":78},2,[41,80,82],{"emptyLinePlaceholder":81},true,"\n",[41,84,86,90,93,96,98,101,105,108,111,113,116,118,121],{"class":43,"line":85},3,[41,87,89],{"class":88},"spNyl","const",[41,91,92],{"class":55}," consoleSpy ",[41,94,95],{"class":51},"=",[41,97,56],{"class":55},[41,99,100],{"class":51},".",[41,102,104],{"class":103},"s2Zo4","spyOn",[41,106,107],{"class":55},"(console",[41,109,110],{"class":51},",",[41,112,65],{"class":51},[41,114,115],{"class":68},"log",[41,117,72],{"class":51},[41,119,120],{"class":55},")",[41,122,75],{"class":51},[41,124,126],{"class":43,"line":125},4,[41,127,82],{"emptyLinePlaceholder":81},[41,129,131,134,137,139,142,144,146,148,151,153,155],{"class":43,"line":130},5,[41,132,133],{"class":103},"logUserAction",[41,135,136],{"class":55},"(",[41,138,72],{"class":51},[41,140,141],{"class":68},"click",[41,143,72],{"class":51},[41,145,110],{"class":51},[41,147,65],{"class":51},[41,149,150],{"class":68},"button",[41,152,72],{"class":51},[41,154,120],{"class":55},[41,156,75],{"class":51},[41,158,160],{"class":43,"line":159},6,[41,161,82],{"emptyLinePlaceholder":81},[41,163,165,168,171,173,176,178,180,183,185,187,189,191,193,195,197,199,201,203],{"class":43,"line":164},7,[41,166,167],{"class":103},"expect",[41,169,170],{"class":55},"(consoleSpy)",[41,172,100],{"class":51},[41,174,175],{"class":103},"toHaveBeenCalledWith",[41,177,136],{"class":55},[41,179,72],{"class":51},[41,181,182],{"class":68},"USER_ACTION",[41,184,72],{"class":51},[41,186,110],{"class":51},[41,188,65],{"class":51},[41,190,141],{"class":68},[41,192,72],{"class":51},[41,194,110],{"class":51},[41,196,65],{"class":51},[41,198,150],{"class":68},[41,200,72],{"class":51},[41,202,120],{"class":55},[41,204,75],{"class":51},[41,206,208,211,213,216,219],{"class":43,"line":207},8,[41,209,210],{"class":55},"consoleSpy",[41,212,100],{"class":51},[41,214,215],{"class":103},"mockRestore",[41,217,218],{"class":55},"()",[41,220,75],{"class":51},[11,222,224],{"id":223},"when-youll-hear-this","When You'll Hear This",[16,226,227],{},"\"Add a spy to check that the analytics event fires on submit.\" \u002F \"The spy confirmed the callback was called twice, which explains the bug.\"",[229,230,231],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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 .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":36,"searchDepth":78,"depth":78,"links":233},[234,235,236,237],{"id":13,"depth":78,"text":14},{"id":21,"depth":78,"text":22},{"id":28,"depth":78,"text":29},{"id":223,"depth":78,"text":224},"testing","A spy is like a double agent — it lets the real function still do its job, but secretly records everything: how many times it was called, with what argumen...","intermediate","md","s",{},"\u002Fterms\u002Fs\u002Fspy",[246,247,248,249],"Mock","Stub","Test Double","Assertion",{"title":5,"description":239},{"changefreq":252,"priority":253},"weekly",0.7,"terms\u002Fs\u002Fspy","_XiWAg39f4BxuByzIPJoLrPMf_pEvLqXdZXr3eXqaY8",[257,261,264,267],{"title":249,"path":258,"acronym":6,"category":238,"difficulty":259,"description":260},"\u002Fterms\u002Fa\u002Fassertion","beginner","An assertion is your test saying 'I DEMAND this is true!'. It's you checking that the result is what you expected.",{"title":246,"path":262,"acronym":6,"category":238,"difficulty":259,"description":263},"\u002Fterms\u002Fm\u002Fmock","A mock is a fake version of something your code talks to.",{"title":247,"path":265,"acronym":6,"category":238,"difficulty":259,"description":266},"\u002Fterms\u002Fs\u002Fstub","A stub is like a cardboard cutout of a function. It stands in for the real thing and always gives you the same canned response.",{"title":248,"path":268,"acronym":6,"category":238,"difficulty":240,"description":269},"\u002Fterms\u002Ft\u002Ftest-double","Test double is the umbrella term for anything that replaces a real dependency in a test. Mocks, stubs, spies, fakes — they're all test doubles.",1776518314709]