[{"data":1,"prerenderedAt":1286},["ShallowReactive",2],{"navigation":3,"docs-path-index":340,"-docs-modules-testing-dependencies":446,"-docs-modules-testing-dependencies-surround":1281},[4],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":64},"Docs","i-lucide-book-marked","\u002Fdocs","docs",[10,30,65,293,318],{"title":11,"path":12,"stem":13,"children":14,"icon":29},"Getting Started","\u002Fdocs\u002Fgetting-started","docs\u002F1.getting-started\u002F1.index",[15,17,21,25],{"title":16,"path":12,"stem":13},"Introduction",{"title":18,"path":19,"stem":20},"Installation","\u002Fdocs\u002Fgetting-started\u002Finstallation","docs\u002F1.getting-started\u002F2.installation",{"title":22,"path":23,"stem":24},"Examples","\u002Fdocs\u002Fgetting-started\u002Fexamples","docs\u002F1.getting-started\u002F3.examples",{"title":26,"path":27,"stem":28},"Project Generator","\u002Fdocs\u002Fgetting-started\u002Fproject-generator","docs\u002F1.getting-started\u002F4.project-generator","i-lucide-rocket",{"title":31,"icon":32,"path":33,"stem":34,"children":35,"page":64},"Core features","i-lucide-square-function","\u002Fdocs\u002Fcore-features","docs\u002F2.core-features",[36,40,44,48,52,56,60],{"title":37,"path":38,"stem":39},"Configuration","\u002Fdocs\u002Fcore-features\u002Fconfiguration","docs\u002F2.core-features\u002F0.configuration",{"title":41,"path":42,"stem":43},"Dependency Injection","\u002Fdocs\u002Fcore-features\u002Fcontainer","docs\u002F2.core-features\u002F1.container",{"title":45,"path":46,"stem":47},"Controllers","\u002Fdocs\u002Fcore-features\u002Fcontrollers","docs\u002F2.core-features\u002F2.controllers",{"title":49,"path":50,"stem":51},"Middlewares","\u002Fdocs\u002Fcore-features\u002Fmiddlewares","docs\u002F2.core-features\u002F3.middlewares",{"title":53,"path":54,"stem":55},"Validation","\u002Fdocs\u002Fcore-features\u002Fvalidation","docs\u002F2.core-features\u002F4.validation",{"title":57,"path":58,"stem":59},"Introspection","\u002Fdocs\u002Fcore-features\u002Fintrospection","docs\u002F2.core-features\u002F5.introspection",{"title":61,"path":62,"stem":63},"Health Checks","\u002Fdocs\u002Fcore-features\u002Fhealth","docs\u002F2.core-features\u002F6.health",false,{"title":66,"icon":67,"defaultOpen":68,"path":69,"stem":70,"children":71,"page":64},"Modules","i-lucide-boxes",true,"\u002Fdocs\u002Fmodules","docs\u002F3.modules",[72,89,100,116,135,154,177,191,206,214,229,240,255,274,282],{"title":73,"icon":64,"defaultOpen":64,"path":74,"stem":75,"children":76,"page":64},"Auth","\u002Fdocs\u002Fmodules\u002Fauth","docs\u002F3.modules\u002F1.auth",[77,81,85],{"title":78,"path":79,"stem":80},"Overview","\u002Fdocs\u002Fmodules\u002Fauth\u002Foverview","docs\u002F3.modules\u002F1.auth\u002F0.overview",{"title":82,"path":83,"stem":84},"Decorators","\u002Fdocs\u002Fmodules\u002Fauth\u002Fdecorators","docs\u002F3.modules\u002F1.auth\u002F1.decorators",{"title":86,"path":87,"stem":88},"API Reference","\u002Fdocs\u002Fmodules\u002Fauth\u002Fapi","docs\u002F3.modules\u002F1.auth\u002F2.api",{"title":90,"icon":64,"defaultOpen":64,"path":91,"stem":92,"children":93,"page":64},"Devtools","\u002Fdocs\u002Fmodules\u002Fdevtools","docs\u002F3.modules\u002F10.devtools",[94,97],{"title":78,"path":95,"stem":96},"\u002Fdocs\u002Fmodules\u002Fdevtools\u002Foverview","docs\u002F3.modules\u002F10.devtools\u002F0.overview",{"title":37,"path":98,"stem":99},"\u002Fdocs\u002Fmodules\u002Fdevtools\u002Fconfiguration","docs\u002F3.modules\u002F10.devtools\u002F1.configuration",{"title":101,"icon":64,"defaultOpen":64,"path":102,"stem":103,"children":104,"page":64},"Telemetry","\u002Fdocs\u002Fmodules\u002Ftelemetry","docs\u002F3.modules\u002F11.telemetry",[105,108,112],{"title":78,"path":106,"stem":107},"\u002Fdocs\u002Fmodules\u002Ftelemetry\u002Foverview","docs\u002F3.modules\u002F11.telemetry\u002F0.overview",{"title":109,"path":110,"stem":111},"API","\u002Fdocs\u002Fmodules\u002Ftelemetry\u002Fapi","docs\u002F3.modules\u002F11.telemetry\u002F1.api",{"title":113,"path":114,"stem":115},"Instrumentation","\u002Fdocs\u002Fmodules\u002Ftelemetry\u002Finstrumentation","docs\u002F3.modules\u002F11.telemetry\u002F2.instrumentation",{"title":117,"icon":64,"defaultOpen":64,"path":118,"stem":119,"children":120,"page":64},"Queue","\u002Fdocs\u002Fmodules\u002Fqueue","docs\u002F3.modules\u002F12.queue",[121,124,128,132],{"title":78,"path":122,"stem":123},"\u002Fdocs\u002Fmodules\u002Fqueue\u002Foverview","docs\u002F3.modules\u002F12.queue\u002F0.overview",{"title":125,"path":126,"stem":127},"Consumers","\u002Fdocs\u002Fmodules\u002Fqueue\u002Fconsumers","docs\u002F3.modules\u002F12.queue\u002F1.consumers",{"title":129,"path":130,"stem":131},"Strategies","\u002Fdocs\u002Fmodules\u002Fqueue\u002Fstrategies","docs\u002F3.modules\u002F12.queue\u002F2.strategies",{"title":109,"path":133,"stem":134},"\u002Fdocs\u002Fmodules\u002Fqueue\u002Fapi","docs\u002F3.modules\u002F12.queue\u002F3.api",{"title":136,"icon":64,"defaultOpen":64,"path":137,"stem":138,"children":139,"page":64},"Scheduler","\u002Fdocs\u002Fmodules\u002Fscheduler","docs\u002F3.modules\u002F13.scheduler",[140,143,147,151],{"title":78,"path":141,"stem":142},"\u002Fdocs\u002Fmodules\u002Fscheduler\u002Foverview","docs\u002F3.modules\u002F13.scheduler\u002F0.overview",{"title":144,"path":145,"stem":146},"Jobs","\u002Fdocs\u002Fmodules\u002Fscheduler\u002Fjobs","docs\u002F3.modules\u002F13.scheduler\u002F1.jobs",{"title":148,"path":149,"stem":150},"Clustering","\u002Fdocs\u002Fmodules\u002Fscheduler\u002Fclustering","docs\u002F3.modules\u002F13.scheduler\u002F2.clustering",{"title":109,"path":152,"stem":153},"\u002Fdocs\u002Fmodules\u002Fscheduler\u002Fapi","docs\u002F3.modules\u002F13.scheduler\u002F3.api",{"title":155,"icon":64,"defaultOpen":64,"path":156,"stem":157,"children":158,"page":64},"Testing","\u002Fdocs\u002Fmodules\u002Ftesting","docs\u002F3.modules\u002F14.testing",[159,162,166,170,174],{"title":78,"path":160,"stem":161},"\u002Fdocs\u002Fmodules\u002Ftesting\u002Foverview","docs\u002F3.modules\u002F14.testing\u002F0.overview",{"title":163,"path":164,"stem":165},"Requests","\u002Fdocs\u002Fmodules\u002Ftesting\u002Frequests","docs\u002F3.modules\u002F14.testing\u002F1.requests",{"title":167,"path":168,"stem":169},"Dependencies","\u002Fdocs\u002Fmodules\u002Ftesting\u002Fdependencies","docs\u002F3.modules\u002F14.testing\u002F2.dependencies",{"title":171,"path":172,"stem":173},"Extensions","\u002Fdocs\u002Fmodules\u002Ftesting\u002Fextensions","docs\u002F3.modules\u002F14.testing\u002F3.extensions",{"title":109,"path":175,"stem":176},"\u002Fdocs\u002Fmodules\u002Ftesting\u002Fapi","docs\u002F3.modules\u002F14.testing\u002F4.api",{"title":178,"icon":64,"defaultOpen":64,"path":179,"stem":180,"children":181,"page":64},"Client","\u002Fdocs\u002Fmodules\u002Fclient","docs\u002F3.modules\u002F15.client",[182,185,188],{"title":78,"path":183,"stem":184},"\u002Fdocs\u002Fmodules\u002Fclient\u002Foverview","docs\u002F3.modules\u002F15.client\u002F0.overview",{"title":163,"path":186,"stem":187},"\u002Fdocs\u002Fmodules\u002Fclient\u002Frequests","docs\u002F3.modules\u002F15.client\u002F1.requests",{"title":109,"path":189,"stem":190},"\u002Fdocs\u002Fmodules\u002Fclient\u002Fapi","docs\u002F3.modules\u002F15.client\u002F2.api",{"title":192,"icon":64,"defaultOpen":64,"path":193,"stem":194,"children":195,"page":64},"Logger","\u002Fdocs\u002Fmodules\u002Flogger","docs\u002F3.modules\u002F2.logger",[196,199,203],{"title":78,"path":197,"stem":198},"\u002Fdocs\u002Fmodules\u002Flogger\u002Foverview","docs\u002F3.modules\u002F2.logger\u002F0.overview",{"title":200,"path":201,"stem":202},"Drains & Adapters","\u002Fdocs\u002Fmodules\u002Flogger\u002Fdrivers","docs\u002F3.modules\u002F2.logger\u002F1.drivers",{"title":109,"path":204,"stem":205},"\u002Fdocs\u002Fmodules\u002Flogger\u002Fapi","docs\u002F3.modules\u002F2.logger\u002F2.api",{"title":207,"icon":64,"defaultOpen":64,"path":208,"stem":209,"children":210,"page":64},"Serverless","\u002Fdocs\u002Fmodules\u002Fserverless","docs\u002F3.modules\u002F3.serverless",[211],{"title":78,"path":212,"stem":213},"\u002Fdocs\u002Fmodules\u002Fserverless\u002Foverview","docs\u002F3.modules\u002F3.serverless\u002F0.overview",{"title":215,"icon":64,"defaultOpen":64,"path":216,"stem":217,"children":218,"page":64},"Storage","\u002Fdocs\u002Fmodules\u002Fstorage","docs\u002F3.modules\u002F4.storage",[219,222,226],{"title":78,"path":220,"stem":221},"\u002Fdocs\u002Fmodules\u002Fstorage\u002Foverview","docs\u002F3.modules\u002F4.storage\u002F0.overview",{"title":223,"path":224,"stem":225},"Drivers","\u002Fdocs\u002Fmodules\u002Fstorage\u002Fdrivers","docs\u002F3.modules\u002F4.storage\u002F1.drivers",{"title":109,"path":227,"stem":228},"\u002Fdocs\u002Fmodules\u002Fstorage\u002Fapi","docs\u002F3.modules\u002F4.storage\u002F2.api",{"title":230,"icon":64,"defaultOpen":64,"path":231,"stem":232,"children":233,"page":64},"Web Sockets","\u002Fdocs\u002Fmodules\u002Fweb-sockets","docs\u002F3.modules\u002F5.web-sockets",[234,237],{"title":78,"path":235,"stem":236},"\u002Fdocs\u002Fmodules\u002Fweb-sockets\u002Foverview","docs\u002F3.modules\u002F5.web-sockets\u002F0.overview",{"title":109,"path":238,"stem":239},"\u002Fdocs\u002Fmodules\u002Fweb-sockets\u002Fapi","docs\u002F3.modules\u002F5.web-sockets\u002F1.api",{"title":241,"icon":64,"defaultOpen":64,"path":242,"stem":243,"children":244,"page":64},"Schema","\u002Fdocs\u002Fmodules\u002Fschema","docs\u002F3.modules\u002F6.schema",[245,248,251],{"title":78,"path":246,"stem":247},"\u002Fdocs\u002Fmodules\u002Fschema\u002Foverview","docs\u002F3.modules\u002F6.schema\u002F0.overview",{"title":82,"path":249,"stem":250},"\u002Fdocs\u002Fmodules\u002Fschema\u002Fdecorators","docs\u002F3.modules\u002F6.schema\u002F1.decorators",{"title":252,"path":253,"stem":254},"Scalar","\u002Fdocs\u002Fmodules\u002Fschema\u002Fscalar","docs\u002F3.modules\u002F6.schema\u002F2.scalar",{"title":256,"icon":64,"defaultOpen":64,"path":257,"stem":258,"children":259,"page":64},"Nitro","\u002Fdocs\u002Fmodules\u002Fnitro","docs\u002F3.modules\u002F7.nitro",[260,263,266,270],{"title":78,"path":261,"stem":262},"\u002Fdocs\u002Fmodules\u002Fnitro\u002Foverview","docs\u002F3.modules\u002F7.nitro\u002F0.overview",{"title":215,"path":264,"stem":265},"\u002Fdocs\u002Fmodules\u002Fnitro\u002Fstorage","docs\u002F3.modules\u002F7.nitro\u002F1.storage",{"title":267,"path":268,"stem":269},"File-Based Routes","\u002Fdocs\u002Fmodules\u002Fnitro\u002Ffile-based-routes","docs\u002F3.modules\u002F7.nitro\u002F2.file-based-routes",{"title":271,"path":272,"stem":273},"Middleware","\u002Fdocs\u002Fmodules\u002Fnitro\u002Fmiddleware","docs\u002F3.modules\u002F7.nitro\u002F3.middleware",{"title":275,"icon":64,"defaultOpen":64,"path":276,"stem":277,"children":278,"page":64},"Vite","\u002Fdocs\u002Fmodules\u002Fvite","docs\u002F3.modules\u002F8.vite",[279],{"title":78,"path":280,"stem":281},"\u002Fdocs\u002Fmodules\u002Fvite\u002Foverview","docs\u002F3.modules\u002F8.vite\u002F0.overview",{"title":283,"icon":64,"defaultOpen":64,"path":284,"stem":285,"children":286,"page":64},"Cache","\u002Fdocs\u002Fmodules\u002Fcache","docs\u002F3.modules\u002F9.cache",[287,290],{"title":78,"path":288,"stem":289},"\u002Fdocs\u002Fmodules\u002Fcache\u002Foverview","docs\u002F3.modules\u002F9.cache\u002F0.overview",{"title":109,"path":291,"stem":292},"\u002Fdocs\u002Fmodules\u002Fcache\u002Fapi","docs\u002F3.modules\u002F9.cache\u002F1.api",{"title":294,"icon":295,"path":296,"stem":297,"children":298,"page":64},"Deployment","i-lucide-cloud-upload","\u002Fdocs\u002Fdeployment","docs\u002F4.deployment",[299,302,306,310,314],{"title":78,"path":300,"stem":301},"\u002Fdocs\u002Fdeployment\u002Foverview","docs\u002F4.deployment\u002F0.overview",{"title":303,"path":304,"stem":305},"Vercel","\u002Fdocs\u002Fdeployment\u002Fvercel","docs\u002F4.deployment\u002F1.vercel",{"title":307,"path":308,"stem":309},"AWS Lambda","\u002Fdocs\u002Fdeployment\u002Faws-lambda","docs\u002F4.deployment\u002F2.aws-lambda",{"title":311,"path":312,"stem":313},"Azure Functions","\u002Fdocs\u002Fdeployment\u002Fazure-functions","docs\u002F4.deployment\u002F3.azure-functions",{"title":315,"path":316,"stem":317},"Node.js Server","\u002Fdocs\u002Fdeployment\u002Fnode-server","docs\u002F4.deployment\u002F4.node-server",{"title":319,"icon":320,"path":321,"stem":322,"children":323,"page":64},"Advanced","i-lucide-brain","\u002Fdocs\u002Fadvanced","docs\u002F99.advanced",[324,328,332,336],{"title":325,"path":326,"stem":327},"Custom Decorator","\u002Fdocs\u002Fadvanced\u002Fcustom-decorator","docs\u002F99.advanced\u002F1.custom-decorator",{"title":329,"path":330,"stem":331},"Plugins","\u002Fdocs\u002Fadvanced\u002Fcustom-plugin","docs\u002F99.advanced\u002F2.custom-plugin",{"title":333,"path":334,"stem":335},"Custom CLI Command","\u002Fdocs\u002Fadvanced\u002Fcustom-cli-command","docs\u002F99.advanced\u002F3.custom-cli-command",{"title":337,"path":338,"stem":339},"Writing a Recipe","\u002Fdocs\u002Fadvanced\u002Fwriting-a-recipe","docs\u002F99.advanced\u002F4.writing-a-recipe",[341,343,345,346,347,348,349,351,352,353,354,355,356,357,358,360,362,363,364,365,367,368,369,371,372,373,374,376,377,378,379,380,382,383,384,385,386,388,389,390,391,392,393,395,396,397,398,400,401,402,403,405,406,408,409,410,411,413,414,415,417,418,419,420,422,423,424,425,426,428,429,431,432,433,435,436,437,438,439,440,442,443,444,445],{"path":342},"\u002Fdocs\u002F.navigation",{"path":344},"\u002Fdocs\u002Fgetting-started\u002F.navigation",{"path":12},{"path":19},{"path":23},{"path":27},{"path":350},"\u002Fdocs\u002Fcore-features\u002F.navigation",{"path":38},{"path":42},{"path":46},{"path":50},{"path":54},{"path":58},{"path":62},{"path":359},"\u002Fdocs\u002Fmodules\u002F.navigation",{"path":361},"\u002Fdocs\u002Fmodules\u002Fauth\u002F.navigation",{"path":79},{"path":83},{"path":87},{"path":366},"\u002Fdocs\u002Fmodules\u002Fdevtools\u002F.navigation",{"path":95},{"path":98},{"path":370},"\u002Fdocs\u002Fmodules\u002Ftelemetry\u002F.navigation",{"path":106},{"path":110},{"path":114},{"path":375},"\u002Fdocs\u002Fmodules\u002Fqueue\u002F.navigation",{"path":122},{"path":126},{"path":130},{"path":133},{"path":381},"\u002Fdocs\u002Fmodules\u002Fscheduler\u002F.navigation",{"path":141},{"path":145},{"path":149},{"path":152},{"path":387},"\u002Fdocs\u002Fmodules\u002Ftesting\u002F.navigation",{"path":160},{"path":164},{"path":168},{"path":172},{"path":175},{"path":394},"\u002Fdocs\u002Fmodules\u002Fclient\u002F.navigation",{"path":183},{"path":186},{"path":189},{"path":399},"\u002Fdocs\u002Fmodules\u002Flogger\u002F.navigation",{"path":197},{"path":201},{"path":204},{"path":404},"\u002Fdocs\u002Fmodules\u002Fserverless\u002F.navigation",{"path":212},{"path":407},"\u002Fdocs\u002Fmodules\u002Fstorage\u002F.navigation",{"path":220},{"path":224},{"path":227},{"path":412},"\u002Fdocs\u002Fmodules\u002Fweb-sockets\u002F.navigation",{"path":235},{"path":238},{"path":416},"\u002Fdocs\u002Fmodules\u002Fschema\u002F.navigation",{"path":246},{"path":249},{"path":253},{"path":421},"\u002Fdocs\u002Fmodules\u002Fnitro\u002F.navigation",{"path":261},{"path":264},{"path":268},{"path":272},{"path":427},"\u002Fdocs\u002Fmodules\u002Fvite\u002F.navigation",{"path":280},{"path":430},"\u002Fdocs\u002Fmodules\u002Fcache\u002F.navigation",{"path":288},{"path":291},{"path":434},"\u002Fdocs\u002Fdeployment\u002F.navigation",{"path":300},{"path":304},{"path":308},{"path":312},{"path":316},{"path":441},"\u002Fdocs\u002Fadvanced\u002F.navigation",{"path":326},{"path":330},{"path":334},{"path":338},{"id":447,"title":167,"body":448,"description":1275,"extension":1276,"links":1277,"meta":1278,"navigation":68,"path":168,"seo":1279,"stem":169,"__hash__":1280},"docs\u002Fdocs\u002F3.modules\u002F14.testing\u002F2.dependencies.md",{"type":449,"value":450,"toc":1269},"minimark",[451,456,467,736,743,750,754,764,876,885,895,899,909,1063,1067,1084,1216,1254,1265],[452,453,455],"h2",{"id":454},"overrides","Overrides",[457,458,459,462,463,466],"p",{},[460,461,454],"code",{}," replaces a dependency with an object or a class: ",[460,464,465],{},"[key, replacement]",".",[468,469,474],"pre",{"className":470,"code":471,"language":472,"meta":473,"style":473},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","const sent: string[] = [];\n\nconst app = await createTestApp({\n  controllers: [SignupController],\n  providers: [UserService, Mailer],\n  overrides: [\n    [UserRepository, { save: async (user) => ({ ...user, id: '1' }) }],\n    [Mailer, { send: async (to: string) => void sent.push(to) }],\n    [Clock, FixedClock],\n  ],\n});\n","ts","",[460,475,476,509,515,539,554,573,584,657,706,719,727],{"__ignoreMap":473},[477,478,481,485,489,493,497,500,503,506],"span",{"class":479,"line":480},"line",1,[477,482,484],{"class":483},"spNyl","const",[477,486,488],{"class":487},"sTEyZ"," sent",[477,490,492],{"class":491},"sMK4o",":",[477,494,496],{"class":495},"sBMFI"," string",[477,498,499],{"class":487},"[] ",[477,501,502],{"class":491},"=",[477,504,505],{"class":487}," []",[477,507,508],{"class":491},";\n",[477,510,512],{"class":479,"line":511},2,[477,513,514],{"emptyLinePlaceholder":68},"\n",[477,516,518,520,523,525,529,533,536],{"class":479,"line":517},3,[477,519,484],{"class":483},[477,521,522],{"class":487}," app ",[477,524,502],{"class":491},[477,526,528],{"class":527},"s7zQu"," await",[477,530,532],{"class":531},"s2Zo4"," createTestApp",[477,534,535],{"class":487},"(",[477,537,538],{"class":491},"{\n",[477,540,542,546,548,551],{"class":479,"line":541},4,[477,543,545],{"class":544},"swJcz","  controllers",[477,547,492],{"class":491},[477,549,550],{"class":487}," [SignupController]",[477,552,553],{"class":491},",\n",[477,555,557,560,562,565,568,571],{"class":479,"line":556},5,[477,558,559],{"class":544},"  providers",[477,561,492],{"class":491},[477,563,564],{"class":487}," [UserService",[477,566,567],{"class":491},",",[477,569,570],{"class":487}," Mailer]",[477,572,553],{"class":491},[477,574,576,579,581],{"class":479,"line":575},6,[477,577,578],{"class":544},"  overrides",[477,580,492],{"class":491},[477,582,583],{"class":487}," [\n",[477,585,587,590,592,595,598,600,603,606,610,613,616,618,621,624,626,628,631,633,636,640,643,646,649,652,655],{"class":479,"line":586},7,[477,588,589],{"class":487},"    [UserRepository",[477,591,567],{"class":491},[477,593,594],{"class":491}," {",[477,596,597],{"class":531}," save",[477,599,492],{"class":491},[477,601,602],{"class":483}," async",[477,604,605],{"class":491}," (",[477,607,609],{"class":608},"sHdIc","user",[477,611,612],{"class":491},")",[477,614,615],{"class":483}," =>",[477,617,605],{"class":487},[477,619,620],{"class":491},"{",[477,622,623],{"class":491}," ...",[477,625,609],{"class":487},[477,627,567],{"class":491},[477,629,630],{"class":544}," id",[477,632,492],{"class":491},[477,634,635],{"class":491}," '",[477,637,639],{"class":638},"sfazB","1",[477,641,642],{"class":491},"'",[477,644,645],{"class":491}," }",[477,647,648],{"class":487},") ",[477,650,651],{"class":491},"}",[477,653,654],{"class":487},"]",[477,656,553],{"class":491},[477,658,660,663,665,667,670,672,674,676,679,681,683,685,687,690,692,694,697,700,702,704],{"class":479,"line":659},8,[477,661,662],{"class":487},"    [Mailer",[477,664,567],{"class":491},[477,666,594],{"class":491},[477,668,669],{"class":531}," send",[477,671,492],{"class":491},[477,673,602],{"class":483},[477,675,605],{"class":491},[477,677,678],{"class":608},"to",[477,680,492],{"class":491},[477,682,496],{"class":495},[477,684,612],{"class":491},[477,686,615],{"class":483},[477,688,689],{"class":491}," void",[477,691,488],{"class":487},[477,693,466],{"class":491},[477,695,696],{"class":531},"push",[477,698,699],{"class":487},"(to) ",[477,701,651],{"class":491},[477,703,654],{"class":487},[477,705,553],{"class":491},[477,707,709,712,714,717],{"class":479,"line":708},9,[477,710,711],{"class":487},"    [Clock",[477,713,567],{"class":491},[477,715,716],{"class":487}," FixedClock]",[477,718,553],{"class":491},[477,720,722,725],{"class":479,"line":721},10,[477,723,724],{"class":487},"  ]",[477,726,553],{"class":491},[477,728,730,732,734],{"class":479,"line":729},11,[477,731,651],{"class":491},[477,733,612],{"class":487},[477,735,508],{"class":491},[457,737,738,739,742],{},"An object is bound as the instance itself, a class is bound as a singleton and gets its own ",[460,740,741],{},"@Inject()","s. Overrides are applied once every plugin has been applied, so they win over a binding a plugin makes.",[457,744,745,746,749],{},"They have to be declared when the app boots. A service that already exists holds the dependency it was given, so replacing a binding afterwards would reach some services and not others. ",[460,747,748],{},"app.override()"," exists only to say so, and always throws.",[452,751,753],{"id":752},"stub","stub()",[457,755,756,757,760,761,763],{},"A partial object is fine as long as the code under test only calls what it defines. When it calls something else, the failure is usually ",[460,758,759],{},"undefined is not a function"," somewhere far from the cause. ",[460,762,753],{}," names it instead:",[468,765,767],{"className":470,"code":766,"language":472,"meta":473,"style":473},"import { stub } from '@vercube\u002Ftesting';\n\nconst repo = stub\u003CUserRepository>({ findById: async () => user }, 'UserRepository');\n\nawait repo.save(user); \u002F\u002F TestingError: UserRepository.save is not stubbed\n",[460,768,769,793,797,849,853],{"__ignoreMap":473},[477,770,771,774,776,779,781,784,786,789,791],{"class":479,"line":480},[477,772,773],{"class":527},"import",[477,775,594],{"class":491},[477,777,778],{"class":487}," stub",[477,780,645],{"class":491},[477,782,783],{"class":527}," from",[477,785,635],{"class":491},[477,787,788],{"class":638},"@vercube\u002Ftesting",[477,790,642],{"class":491},[477,792,508],{"class":491},[477,794,795],{"class":479,"line":511},[477,796,514],{"emptyLinePlaceholder":68},[477,798,799,801,804,806,808,811,814,817,819,821,824,826,828,831,833,836,839,841,843,845,847],{"class":479,"line":517},[477,800,484],{"class":483},[477,802,803],{"class":487}," repo ",[477,805,502],{"class":491},[477,807,778],{"class":531},[477,809,810],{"class":491},"\u003C",[477,812,813],{"class":495},"UserRepository",[477,815,816],{"class":491},">",[477,818,535],{"class":487},[477,820,620],{"class":491},[477,822,823],{"class":531}," findById",[477,825,492],{"class":491},[477,827,602],{"class":483},[477,829,830],{"class":491}," ()",[477,832,615],{"class":483},[477,834,835],{"class":487}," user ",[477,837,838],{"class":491},"},",[477,840,635],{"class":491},[477,842,813],{"class":638},[477,844,642],{"class":491},[477,846,612],{"class":487},[477,848,508],{"class":491},[477,850,851],{"class":479,"line":541},[477,852,514],{"emptyLinePlaceholder":68},[477,854,855,858,861,863,866,869,872],{"class":479,"line":556},[477,856,857],{"class":527},"await",[477,859,860],{"class":487}," repo",[477,862,466],{"class":491},[477,864,865],{"class":531},"save",[477,867,868],{"class":487},"(user)",[477,870,871],{"class":491},";",[477,873,875],{"class":874},"sHwdD"," \u002F\u002F TestingError: UserRepository.save is not stubbed\n",[457,877,878,881,882,884],{},[460,879,880],{},"strictOverrides: true"," wraps every object override with ",[460,883,753],{},", named after its key. It is off by default.",[457,886,887,888,891,892,466],{},"A stub is not a promise, so ",[460,889,890],{},"await stub()"," resolves to the stub. Members it does not define read as a function that throws, so check an optional property with ",[460,893,894],{},"'name' in stub",[452,896,898],{"id":897},"services-without-http","Services without HTTP",[457,900,901,904,905,908],{},[460,902,903],{},"createTestContainer()"," builds a bare container for unit tests of services. ",[460,906,907],{},"@Init()"," methods run, as they would in an app.",[468,910,912],{"className":470,"code":911,"language":472,"meta":473,"style":473},"import { createTestContainer } from '@vercube\u002Ftesting';\n\nconst { container, logs } = createTestContainer({\n  providers: [PriceService],\n  overrides: [[ExchangeRates, { rate: () => 4.3 }]],\n});\n\nexpect(container.get(PriceService).toPln(10)).toBe(43);\n",[460,913,914,935,939,964,975,1008,1016,1020],{"__ignoreMap":473},[477,915,916,918,920,923,925,927,929,931,933],{"class":479,"line":480},[477,917,773],{"class":527},[477,919,594],{"class":491},[477,921,922],{"class":487}," createTestContainer",[477,924,645],{"class":491},[477,926,783],{"class":527},[477,928,635],{"class":491},[477,930,788],{"class":638},[477,932,642],{"class":491},[477,934,508],{"class":491},[477,936,937],{"class":479,"line":511},[477,938,514],{"emptyLinePlaceholder":68},[477,940,941,943,945,948,950,953,955,958,960,962],{"class":479,"line":517},[477,942,484],{"class":483},[477,944,594],{"class":491},[477,946,947],{"class":487}," container",[477,949,567],{"class":491},[477,951,952],{"class":487}," logs ",[477,954,651],{"class":491},[477,956,957],{"class":491}," =",[477,959,922],{"class":531},[477,961,535],{"class":487},[477,963,538],{"class":491},[477,965,966,968,970,973],{"class":479,"line":541},[477,967,559],{"class":544},[477,969,492],{"class":491},[477,971,972],{"class":487}," [PriceService]",[477,974,553],{"class":491},[477,976,977,979,981,984,986,988,991,993,995,997,1001,1003,1006],{"class":479,"line":556},[477,978,578],{"class":544},[477,980,492],{"class":491},[477,982,983],{"class":487}," [[ExchangeRates",[477,985,567],{"class":491},[477,987,594],{"class":491},[477,989,990],{"class":531}," rate",[477,992,492],{"class":491},[477,994,830],{"class":491},[477,996,615],{"class":483},[477,998,1000],{"class":999},"sbssI"," 4.3",[477,1002,645],{"class":491},[477,1004,1005],{"class":487},"]]",[477,1007,553],{"class":491},[477,1009,1010,1012,1014],{"class":479,"line":575},[477,1011,651],{"class":491},[477,1013,612],{"class":487},[477,1015,508],{"class":491},[477,1017,1018],{"class":479,"line":586},[477,1019,514],{"emptyLinePlaceholder":68},[477,1021,1022,1025,1028,1030,1033,1036,1038,1041,1043,1046,1049,1051,1054,1056,1059,1061],{"class":479,"line":659},[477,1023,1024],{"class":531},"expect",[477,1026,1027],{"class":487},"(container",[477,1029,466],{"class":491},[477,1031,1032],{"class":531},"get",[477,1034,1035],{"class":487},"(PriceService)",[477,1037,466],{"class":491},[477,1039,1040],{"class":531},"toPln",[477,1042,535],{"class":487},[477,1044,1045],{"class":999},"10",[477,1047,1048],{"class":487},"))",[477,1050,466],{"class":491},[477,1052,1053],{"class":531},"toBe",[477,1055,535],{"class":487},[477,1057,1058],{"class":999},"43",[477,1060,612],{"class":487},[477,1062,508],{"class":491},[452,1064,1066],{"id":1065},"logs","Logs",[457,1068,1069,1072,1073,1076,1077,1079,1080,1083],{},[460,1070,1071],{},"createTestApp()"," binds a ",[460,1074,1075],{},"TestLogger"," as the ",[460,1078,192],{}," and exposes it as ",[460,1081,1082],{},"app.logs",". It keeps every call instead of writing it out, including what the framework itself logs, such as an unhandled error in a handler.",[468,1085,1087],{"className":470,"code":1086,"language":472,"meta":473,"style":473},"await app.get('\u002Forders\u002F404').expect(500);\n\nexpect(app.logs.find('error', \u002Forder not found\u002F)).toBeDefined();\nexpect(app.logs.filter('warn')).toHaveLength(0);\n",[460,1088,1089,1124,1128,1176],{"__ignoreMap":473},[477,1090,1091,1093,1096,1098,1100,1102,1104,1107,1109,1111,1113,1115,1117,1120,1122],{"class":479,"line":480},[477,1092,857],{"class":527},[477,1094,1095],{"class":487}," app",[477,1097,466],{"class":491},[477,1099,1032],{"class":531},[477,1101,535],{"class":487},[477,1103,642],{"class":491},[477,1105,1106],{"class":638},"\u002Forders\u002F404",[477,1108,642],{"class":491},[477,1110,612],{"class":487},[477,1112,466],{"class":491},[477,1114,1024],{"class":531},[477,1116,535],{"class":487},[477,1118,1119],{"class":999},"500",[477,1121,612],{"class":487},[477,1123,508],{"class":491},[477,1125,1126],{"class":479,"line":511},[477,1127,514],{"emptyLinePlaceholder":68},[477,1129,1130,1132,1135,1137,1139,1141,1144,1146,1148,1151,1153,1155,1158,1161,1164,1166,1168,1171,1174],{"class":479,"line":517},[477,1131,1024],{"class":531},[477,1133,1134],{"class":487},"(app",[477,1136,466],{"class":491},[477,1138,1065],{"class":487},[477,1140,466],{"class":491},[477,1142,1143],{"class":531},"find",[477,1145,535],{"class":487},[477,1147,642],{"class":491},[477,1149,1150],{"class":638},"error",[477,1152,642],{"class":491},[477,1154,567],{"class":491},[477,1156,1157],{"class":491}," \u002F",[477,1159,1160],{"class":638},"order not found",[477,1162,1163],{"class":491},"\u002F",[477,1165,1048],{"class":487},[477,1167,466],{"class":491},[477,1169,1170],{"class":531},"toBeDefined",[477,1172,1173],{"class":487},"()",[477,1175,508],{"class":491},[477,1177,1178,1180,1182,1184,1186,1188,1191,1193,1195,1198,1200,1202,1204,1207,1209,1212,1214],{"class":479,"line":541},[477,1179,1024],{"class":531},[477,1181,1134],{"class":487},[477,1183,466],{"class":491},[477,1185,1065],{"class":487},[477,1187,466],{"class":491},[477,1189,1190],{"class":531},"filter",[477,1192,535],{"class":487},[477,1194,642],{"class":491},[477,1196,1197],{"class":638},"warn",[477,1199,642],{"class":491},[477,1201,1048],{"class":487},[477,1203,466],{"class":491},[477,1205,1206],{"class":531},"toHaveLength",[477,1208,535],{"class":487},[477,1210,1211],{"class":999},"0",[477,1213,612],{"class":487},[477,1215,508],{"class":491},[457,1217,1218,1221,1222,1225,1226,1229,1230,1229,1233,1229,1236,1221,1239,1242,1243,1246,1247,1250,1251,466],{},[460,1219,1220],{},"find()"," and ",[460,1223,1224],{},"filter()"," take a level and a match: a substring of the message, a RegExp, or a predicate over the record. Each record has ",[460,1227,1228],{},"level",", ",[460,1231,1232],{},"args",[460,1234,1235],{},"message",[460,1237,1238],{},"context",[460,1240,1241],{},"at",". Children made with ",[460,1244,1245],{},"logger.child()"," write to the same records with their context merged in, and ",[460,1248,1249],{},"emit()"," is recorded with the level ",[460,1252,1253],{},"wide-event",[457,1255,1256,1257,1260,1261,1264],{},"Set ",[460,1258,1259],{},"app.logs.print = true"," to see the logs while debugging a test, and pass ",[460,1262,1263],{},"logger: false"," to keep the logger your configuration binds.",[1266,1267,1268],"style",{},"html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}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 .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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);}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":473,"searchDepth":480,"depth":511,"links":1270},[1271,1272,1273,1274],{"id":454,"depth":511,"text":455},{"id":752,"depth":511,"text":753},{"id":897,"depth":511,"text":898},{"id":1065,"depth":511,"text":1066},"Replace services with fakes, stub only what a test needs, test services without HTTP, and assert on logs","md",null,{},{"title":167,"description":1275},"kuQod9hUzE_9WsWZEQVqLJe6BzWBzrUhB5W2Jnqdi8E",[1282,1284],{"title":163,"path":164,"stem":165,"description":1283,"children":-1},"Send requests through the app under test, check the status and headers, and read the response",{"title":171,"path":172,"stem":173,"description":1285,"children":-1},"Authenticated requests, recorded spans, a clock the test controls, an in-memory queue and storage",1794396677483]