[{"data":1,"prerenderedAt":306},["ShallowReactive",2],{"navigation":3,"\u002Fgetting-started\u002Ftesting":115,"\u002Fgetting-started\u002Ftesting-surround":301},[4,36,57,88,104],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":35},"Getting Started","i-lucide-rocket","\u002Fgetting-started","1.getting-started",[10,15,20,25,30],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction","i-lucide-info",{"title":16,"path":17,"stem":18,"icon":19},"Install","\u002Fgetting-started\u002Finstall","1.getting-started\u002F2.install","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":24},"Quickstart","\u002Fgetting-started\u002Fquickstart","1.getting-started\u002F3.quickstart","i-lucide-zap",{"title":26,"path":27,"stem":28,"icon":29},"Testing","\u002Fgetting-started\u002Ftesting","1.getting-started\u002F4.testing","i-lucide-flask-conical",{"title":31,"path":32,"stem":33,"icon":34},"CLI","\u002Fgetting-started\u002Fcli","1.getting-started\u002F5.cli","i-lucide-terminal",false,{"title":37,"icon":38,"path":39,"stem":40,"children":41,"page":35},"Concepts","i-lucide-boxes","\u002Fconcepts","2.concepts",[42,47,52],{"title":43,"path":44,"stem":45,"icon":46},"SQL-first contract","\u002Fconcepts\u002Fsql-first-contract","2.concepts\u002F1.sql-first-contract","i-lucide-database",{"title":48,"path":49,"stem":50,"icon":51},"Jobs and status","\u002Fconcepts\u002Fjobs-and-status","2.concepts\u002F2.jobs-and-status","i-lucide-list-checks",{"title":53,"path":54,"stem":55,"icon":56},"Fencing and settles","\u002Fconcepts\u002Ffencing-and-settles","2.concepts\u002F3.fencing-and-settles","i-lucide-shield",{"title":58,"icon":59,"path":60,"stem":61,"children":62,"page":35},"API","i-lucide-code-2","\u002Fapi","3.api",[63,68,73,78,83],{"title":64,"path":65,"stem":66,"icon":67},"Enqueue","\u002Fapi\u002Fenqueue","3.api\u002F1.enqueue","i-lucide-plus-circle",{"title":69,"path":70,"stem":71,"icon":72},"Claim and heartbeat","\u002Fapi\u002Fclaim-and-heartbeat","3.api\u002F2.claim-and-heartbeat","i-lucide-hand",{"title":74,"path":75,"stem":76,"icon":77},"Worker and handlers","\u002Fapi\u002Fworker-and-handlers","3.api\u002F3.worker-and-handlers","i-lucide-cpu",{"title":79,"path":80,"stem":81,"icon":82},"HTTP facade","\u002Fapi\u002Fhttp-facade","3.api\u002F4.http-facade","i-lucide-globe",{"title":84,"path":85,"stem":86,"icon":87},"Authorization","\u002Fapi\u002Fauthorization","3.api\u002F5.authorization","i-lucide-key-round",{"title":89,"icon":90,"path":91,"stem":92,"children":93,"page":35},"Operations","i-lucide-activity","\u002Foperations","4.operations",[94,99],{"title":95,"path":96,"stem":97,"icon":98},"Housekeeping","\u002Foperations\u002Fhousekeeping","4.operations\u002F1.housekeeping","i-lucide-timer",{"title":100,"path":101,"stem":102,"icon":103},"Redrive and dead letters","\u002Foperations\u002Fredrive-and-dlq","4.operations\u002F2.redrive-and-dlq","i-lucide-rotate-ccw",{"title":105,"icon":106,"path":107,"stem":108,"children":109,"page":35},"Reference","i-lucide-book-marked","\u002Freference","5.reference",[110],{"title":111,"path":112,"stem":113,"icon":114},"Configuration","\u002Freference\u002Fconfiguration","5.reference\u002F1.configuration","i-lucide-settings",{"id":116,"title":26,"body":117,"description":294,"extension":295,"links":296,"meta":297,"navigation":298,"path":27,"seo":299,"stem":28,"__hash__":300},"docs\u002F1.getting-started\u002F4.testing.md",{"type":118,"value":119,"toc":290},"minimark",[120,124,185,190,193,221,225,228,252,263,286],[121,122,123],"p",{},"Consumer tests can replace the producer facade without starting a worker or database.",[125,126,131],"pre",{"className":127,"code":128,"language":129,"meta":130,"style":130},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","from taskq.testing import FakeTaskQClient\n\nwith tq.replace_client(FakeTaskQClient()) as fake:\n    await application_call()\n    fake.assert_enqueued(\n        \"mail.send\",\n        where={\"payload.recipient\": \"me@example.test\"},\n    )\n","python","",[132,133,134,142,149,155,161,167,173,179],"code",{"__ignoreMap":130},[135,136,139],"span",{"class":137,"line":138},"line",1,[135,140,141],{},"from taskq.testing import FakeTaskQClient\n",[135,143,145],{"class":137,"line":144},2,[135,146,148],{"emptyLinePlaceholder":147},true,"\n",[135,150,152],{"class":137,"line":151},3,[135,153,154],{},"with tq.replace_client(FakeTaskQClient()) as fake:\n",[135,156,158],{"class":137,"line":157},4,[135,159,160],{},"    await application_call()\n",[135,162,164],{"class":137,"line":163},5,[135,165,166],{},"    fake.assert_enqueued(\n",[135,168,170],{"class":137,"line":169},6,[135,171,172],{},"        \"mail.send\",\n",[135,174,176],{"class":137,"line":175},7,[135,177,178],{},"        where={\"payload.recipient\": \"me@example.test\"},\n",[135,180,182],{"class":137,"line":181},8,[135,183,184],{},"    )\n",[186,187,189],"h2",{"id":188},"inline-mode","Inline mode",[121,191,192],{},"Execute registered handlers immediately in-process:",[125,194,196],{"className":127,"code":195,"language":129,"meta":130,"style":130},"from taskq.testing import inline_mode\n\nasync with inline_mode(tq) as recorder:\n    await application_call()\n    assert recorder.settled(\"mail.send\")[0].is_complete\n",[132,197,198,203,207,212,216],{"__ignoreMap":130},[135,199,200],{"class":137,"line":138},[135,201,202],{},"from taskq.testing import inline_mode\n",[135,204,205],{"class":137,"line":144},[135,206,148],{"emptyLinePlaceholder":147},[135,208,209],{"class":137,"line":151},[135,210,211],{},"async with inline_mode(tq) as recorder:\n",[135,213,214],{"class":137,"line":157},[135,215,160],{},[135,217,218],{"class":137,"line":163},[135,219,220],{},"    assert recorder.settled(\"mail.send\")[0].is_complete\n",[186,222,224],{"id":223},"drain","Drain",[121,226,227],{},"Run a bounded claim\u002Fsettle loop against a real (or fake) transport without sleeps:",[125,229,231],{"className":127,"code":230,"language":129,"meta":130,"style":130},"from taskq.testing import drain\n\nreport = await drain(tq, queue=\"mail\", max_jobs=100)\nassert report.completed == 1\n",[132,232,233,238,242,247],{"__ignoreMap":130},[135,234,235],{"class":137,"line":138},[135,236,237],{},"from taskq.testing import drain\n",[135,239,240],{"class":137,"line":144},[135,241,148],{"emptyLinePlaceholder":147},[135,243,244],{"class":137,"line":151},[135,245,246],{},"report = await drain(tq, queue=\"mail\", max_jobs=100)\n",[135,248,249],{"class":137,"line":157},[135,250,251],{},"assert report.completed == 1\n",[121,253,254,255,258,259,262],{},"Also available: ",[132,256,257],{},"work(task=..., payload=...)"," for direct handler invocation and ",[132,260,261],{},"require_enqueued(...)"," for assertion helpers.",[264,265,266],"warning",{},[121,267,268,269,273,274,277,278,281,282,285],{},"These are ",[270,271,272],"strong",{},"consumer-test conveniences",", not production modes. The fake does not model PostgreSQL fencing, privileges, budgets, or transaction isolation. Use a scratch PostgreSQL transaction with ",[132,275,276],{},"work",", ",[132,279,280],{},"require_enqueued",", or ",[132,283,284],{},"drain(..., connection=connection)"," when those contracts matter.",[287,288,289],"style",{},"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":130,"searchDepth":138,"depth":144,"links":291},[292,293],{"id":188,"depth":144,"text":189},{"id":223,"depth":144,"text":224},"Fake clients, inline execution, and bounded drain helpers.","md",null,{},{"icon":29},{"title":26,"description":294},"QNVtP5ifHuYA450VsC_LTNklf0xzkxV5ZFFDaEduYjo",[302,304],{"title":21,"path":22,"stem":23,"description":303,"icon":24,"children":-1},"Migrate, register a task, enqueue, and run a worker.",{"title":31,"path":32,"stem":33,"description":305,"icon":34,"children":-1},"migrate, verify, worker, auth, and taskq-bench.",1784549299452]