[{"data":1,"prerenderedAt":816},["ShallowReactive",2],{"page-\u002Fadvanced-mocking-test-doubles-in-python\u002Fdeep-dive-into-unittestmock\u002Fmock-vs-magicmock-vs-asyncmock-when-to-use-each\u002F":3},{"id":4,"title":5,"body":6,"description":782,"extension":783,"meta":784,"navigation":255,"path":812,"seo":813,"stem":814,"__hash__":815},"content\u002Fadvanced-mocking-test-doubles-in-python\u002Fdeep-dive-into-unittestmock\u002Fmock-vs-magicmock-vs-asyncmock-when-to-use-each\u002Findex.md","Mock vs MagicMock vs AsyncMock — When to Use Each",{"type":7,"value":8,"toc":774},"minimark",[9,50,55,88,220,224,227,532,536,582,586,702,706,712,725,731,735,765,770],[10,11,12,13,17,18,21,22,25,26,29,30,33,34,37,38,40,41,43,44,46,47,49],"p",{},"Every Python test suite eventually hits the question of which test double to instantiate, and the wrong choice produces one of three signature failures: a bare ",[14,15,16],"code",{},"Mock"," blowing up with ",[14,19,20],{},"AttributeError: __enter__"," inside a ",[14,23,24],{},"with"," block, a ",[14,27,28],{},"MagicMock"," raising ",[14,31,32],{},"TypeError: object MagicMock can't be used in 'await' expression",", or an ",[14,35,36],{},"AsyncMock"," silently wrapping a synchronous call in a coroutine nobody awaits. The three classes form a deliberate hierarchy — ",[14,39,28],{}," subclasses ",[14,42,16],{},", and ",[14,45,36],{}," (added in Python 3.8) subclasses ",[14,48,28],{}," — each adding support for one more protocol. This guide gives a decision procedure tied to the exact protocol the code under test relies on, so you pick the class that prevents the failure rather than discovering it in CI.",[51,52,54],"h2",{"id":53},"prerequisites","Prerequisites",[56,57,58,65,71],"ul",{},[59,60,61,62,64],"li",{},"Python 3.8+ for ",[14,63,36],{},"; on 3.7 and earlier you hand-roll awaitable doubles. Examples target 3.11.",[59,66,67,70],{},[14,68,69],{},"unittest.mock"," from the standard library.",[59,72,73,74,77,78,81,82,87],{},"Working knowledge of context managers, the iterator protocol, and ",[14,75,76],{},"async","\u002F",[14,79,80],{},"await",". The ",[83,84,86],"a",{"href":85},"\u002Fadvanced-mocking-test-doubles-in-python\u002Fdeep-dive-into-unittestmock\u002F","Deep Dive into unittest.mock"," covers the shared internals.",[89,90,93,216],"figure",{"className":91},[92],"diagram",[94,95,102,103,102,107,102,111,102,102,121,102,131,102,136,102,139,102,142,102,145,102,102,148,102,155,102,160,102,164,102,166,102,102,168,102,171,102,175,102,179,102,181,102,102,183,102,186,102,190,102,192,102,194,102,102,196,102,199,102,203,102,206,102,208,102,211],"svg",{"viewBox":96,"role":97,"ariaLabelledBy":98,"xmlns":101},"0 0 760 360","img",[99,100],"mvmTITLE","mvmDESC","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","\n  ",[104,105,106],"title",{"id":99},"Mock, MagicMock and AsyncMock feature matrix",[108,109,110],"desc",{"id":100},"A comparison matrix showing which capabilities Mock, MagicMock and AsyncMock support across attribute tracking, dunder protocols and awaitable returns.",[112,113,120],"text",{"x":114,"y":115,"textAnchor":116,"fontSize":117,"fontWeight":118,"fill":119},"380","34","middle","18","700","#3d405b","Which double supports what",[122,123],"rect",{"x":124,"y":125,"width":126,"height":127,"rx":128,"fill":129,"stroke":119,"strokeWidth":130},"270","56","150","40","8","#f4f1de","1.5",[112,132,16],{"x":133,"y":134,"textAnchor":116,"fontSize":135,"fontWeight":118,"fill":119},"345","81","13",[122,137],{"x":138,"y":125,"width":126,"height":127,"rx":128,"fill":129,"stroke":119,"strokeWidth":130},"430",[112,140,28],{"x":141,"y":134,"textAnchor":116,"fontSize":135,"fontWeight":118,"fill":119},"505",[122,143],{"x":144,"y":125,"width":126,"height":127,"rx":128,"fill":129,"stroke":119,"strokeWidth":130},"590",[112,146,36],{"x":147,"y":134,"textAnchor":116,"fontSize":135,"fontWeight":118,"fill":119},"665",[122,149],{"x":150,"y":151,"width":152,"height":127,"rx":128,"fill":153,"stroke":154,"strokeWidth":130},"20","106","240","#fffdf8","rgba(61,64,91,0.14)",[112,156,159],{"x":115,"y":157,"fontSize":158,"fill":119},"131","12","call & attr tracking",[112,161,163],{"x":133,"y":157,"textAnchor":116,"fontSize":158,"fontWeight":118,"fill":162},"#81b29a","yes",[112,165,163],{"x":141,"y":157,"textAnchor":116,"fontSize":158,"fontWeight":118,"fill":162},[112,167,163],{"x":147,"y":157,"textAnchor":116,"fontSize":158,"fontWeight":118,"fill":162},[122,169],{"x":150,"y":170,"width":152,"height":127,"rx":128,"fill":153,"stroke":154,"strokeWidth":130},"156",[112,172,174],{"x":115,"y":173,"fontSize":158,"fill":119},"181","dunder protocols",[112,176,178],{"x":133,"y":173,"textAnchor":116,"fontSize":158,"fontWeight":118,"fill":177},"#e07a5f","no",[112,180,163],{"x":141,"y":173,"textAnchor":116,"fontSize":158,"fontWeight":118,"fill":162},[112,182,163],{"x":147,"y":173,"textAnchor":116,"fontSize":158,"fontWeight":118,"fill":162},[122,184],{"x":150,"y":185,"width":152,"height":127,"rx":128,"fill":153,"stroke":154,"strokeWidth":130},"206",[112,187,189],{"x":115,"y":188,"fontSize":158,"fill":119},"231","awaitable on call",[112,191,178],{"x":133,"y":188,"textAnchor":116,"fontSize":158,"fontWeight":118,"fill":177},[112,193,178],{"x":141,"y":188,"textAnchor":116,"fontSize":158,"fontWeight":118,"fill":177},[112,195,163],{"x":147,"y":188,"textAnchor":116,"fontSize":158,"fontWeight":118,"fill":162},[122,197],{"x":150,"y":198,"width":152,"height":127,"rx":128,"fill":153,"stroke":154,"strokeWidth":130},"256",[112,200,202],{"x":115,"y":201,"fontSize":158,"fill":119},"281","available since",[112,204,205],{"x":133,"y":201,"textAnchor":116,"fontSize":158,"fontWeight":118,"fill":119},"always",[112,207,205],{"x":141,"y":201,"textAnchor":116,"fontSize":158,"fontWeight":118,"fill":119},[112,209,210],{"x":147,"y":201,"textAnchor":116,"fontSize":158,"fontWeight":118,"fill":119},"3.8+",[112,212,215],{"x":114,"y":213,"textAnchor":116,"fontSize":214,"fill":119},"328","11","Each class adds one protocol layer to its parent.",[217,218,219],"figcaption",{},"Mock tracks calls; MagicMock adds dunder protocol support; AsyncMock (3.8+) adds awaitable returns. Pick the lowest layer that covers what the code under test exercises.",[51,221,223],{"id":222},"solution","Solution",[10,225,226],{},"The decision is mechanical: match the class to the protocol the code exercises. Use the lowest layer that still works.",[228,229,234],"pre",{"className":230,"code":231,"language":232,"meta":233,"style":233},"language-python shiki shiki-themes github-light github-dark","import asyncio\nfrom unittest.mock import Mock, MagicMock, AsyncMock, create_autospec\n\n\n# --- 1. Mock: plain calls and attributes. Add spec= for a strict contract. ---\nclass Repo:\n    def get(self, key: str) -> str: ...\n\nrepo = Mock(spec=Repo)              # AttributeError on anything not on Repo\nrepo.get.return_value = \"row\"\nassert repo.get(\"k\") == \"row\"\nrepo.get.assert_called_once_with(\"k\")\n\n\n# --- 2. MagicMock: needed for dunder protocols (with \u002F for \u002F len \u002F []). ---\nconn = MagicMock()                  # __enter__\u002F__exit__ pre-wired\nwith conn as session:               # a bare Mock() raises AttributeError here\n    session.execute(\"SELECT 1\")\nconn.__enter__.assert_called_once()\n\nitems = MagicMock()\nitems.__iter__.return_value = iter([1, 2, 3])\nassert list(items) == [1, 2, 3]     # iteration works because __iter__ exists\n\n\n# --- 3. AsyncMock: required when the double is awaited (Python 3.8+). ---\nclass Client:\n    async def fetch(self, url: str) -> dict: ...\n\nasync def use(client: Client) -> dict:\n    return await client.fetch(\"\u002Fdata\")   # the code under test awaits here\n\nasync def main() -> None:\n    client = AsyncMock(spec=Client)       # call returns an awaitable\n    client.fetch.return_value = {\"ok\": True}\n    result = await use(client)            # MagicMock here -> TypeError on await\n    assert result == {\"ok\": True}\n    client.fetch.assert_awaited_once_with(\"\u002Fdata\")   # await-aware assertion\n\nasyncio.run(main())\n\n\n# --- 4. Let autospec choose per attribute: sync stays Mock\u002FMagicMock,\n#        coroutine functions become AsyncMock automatically. ---\nclass Mixed:\n    def sync_op(self) -> int: ...\n    async def async_op(self) -> int: ...\n\nm = create_autospec(Mixed)\nassert not asyncio.iscoroutinefunction(m.sync_op)\nassert asyncio.iscoroutinefunction(m.async_op)   # picked AsyncMock for you\n","python","",[14,235,236,244,250,257,262,268,274,280,285,291,297,303,309,314,319,325,331,337,343,349,354,360,366,372,377,382,388,394,400,405,411,417,422,428,434,440,446,452,458,463,469,474,479,485,491,497,503,509,514,520,526],{"__ignoreMap":233},[237,238,241],"span",{"class":239,"line":240},"line",1,[237,242,243],{},"import asyncio\n",[237,245,247],{"class":239,"line":246},2,[237,248,249],{},"from unittest.mock import Mock, MagicMock, AsyncMock, create_autospec\n",[237,251,253],{"class":239,"line":252},3,[237,254,256],{"emptyLinePlaceholder":255},true,"\n",[237,258,260],{"class":239,"line":259},4,[237,261,256],{"emptyLinePlaceholder":255},[237,263,265],{"class":239,"line":264},5,[237,266,267],{},"# --- 1. Mock: plain calls and attributes. Add spec= for a strict contract. ---\n",[237,269,271],{"class":239,"line":270},6,[237,272,273],{},"class Repo:\n",[237,275,277],{"class":239,"line":276},7,[237,278,279],{},"    def get(self, key: str) -> str: ...\n",[237,281,283],{"class":239,"line":282},8,[237,284,256],{"emptyLinePlaceholder":255},[237,286,288],{"class":239,"line":287},9,[237,289,290],{},"repo = Mock(spec=Repo)              # AttributeError on anything not on Repo\n",[237,292,294],{"class":239,"line":293},10,[237,295,296],{},"repo.get.return_value = \"row\"\n",[237,298,300],{"class":239,"line":299},11,[237,301,302],{},"assert repo.get(\"k\") == \"row\"\n",[237,304,306],{"class":239,"line":305},12,[237,307,308],{},"repo.get.assert_called_once_with(\"k\")\n",[237,310,312],{"class":239,"line":311},13,[237,313,256],{"emptyLinePlaceholder":255},[237,315,317],{"class":239,"line":316},14,[237,318,256],{"emptyLinePlaceholder":255},[237,320,322],{"class":239,"line":321},15,[237,323,324],{},"# --- 2. MagicMock: needed for dunder protocols (with \u002F for \u002F len \u002F []). ---\n",[237,326,328],{"class":239,"line":327},16,[237,329,330],{},"conn = MagicMock()                  # __enter__\u002F__exit__ pre-wired\n",[237,332,334],{"class":239,"line":333},17,[237,335,336],{},"with conn as session:               # a bare Mock() raises AttributeError here\n",[237,338,340],{"class":239,"line":339},18,[237,341,342],{},"    session.execute(\"SELECT 1\")\n",[237,344,346],{"class":239,"line":345},19,[237,347,348],{},"conn.__enter__.assert_called_once()\n",[237,350,352],{"class":239,"line":351},20,[237,353,256],{"emptyLinePlaceholder":255},[237,355,357],{"class":239,"line":356},21,[237,358,359],{},"items = MagicMock()\n",[237,361,363],{"class":239,"line":362},22,[237,364,365],{},"items.__iter__.return_value = iter([1, 2, 3])\n",[237,367,369],{"class":239,"line":368},23,[237,370,371],{},"assert list(items) == [1, 2, 3]     # iteration works because __iter__ exists\n",[237,373,375],{"class":239,"line":374},24,[237,376,256],{"emptyLinePlaceholder":255},[237,378,380],{"class":239,"line":379},25,[237,381,256],{"emptyLinePlaceholder":255},[237,383,385],{"class":239,"line":384},26,[237,386,387],{},"# --- 3. AsyncMock: required when the double is awaited (Python 3.8+). ---\n",[237,389,391],{"class":239,"line":390},27,[237,392,393],{},"class Client:\n",[237,395,397],{"class":239,"line":396},28,[237,398,399],{},"    async def fetch(self, url: str) -> dict: ...\n",[237,401,403],{"class":239,"line":402},29,[237,404,256],{"emptyLinePlaceholder":255},[237,406,408],{"class":239,"line":407},30,[237,409,410],{},"async def use(client: Client) -> dict:\n",[237,412,414],{"class":239,"line":413},31,[237,415,416],{},"    return await client.fetch(\"\u002Fdata\")   # the code under test awaits here\n",[237,418,420],{"class":239,"line":419},32,[237,421,256],{"emptyLinePlaceholder":255},[237,423,425],{"class":239,"line":424},33,[237,426,427],{},"async def main() -> None:\n",[237,429,431],{"class":239,"line":430},34,[237,432,433],{},"    client = AsyncMock(spec=Client)       # call returns an awaitable\n",[237,435,437],{"class":239,"line":436},35,[237,438,439],{},"    client.fetch.return_value = {\"ok\": True}\n",[237,441,443],{"class":239,"line":442},36,[237,444,445],{},"    result = await use(client)            # MagicMock here -> TypeError on await\n",[237,447,449],{"class":239,"line":448},37,[237,450,451],{},"    assert result == {\"ok\": True}\n",[237,453,455],{"class":239,"line":454},38,[237,456,457],{},"    client.fetch.assert_awaited_once_with(\"\u002Fdata\")   # await-aware assertion\n",[237,459,461],{"class":239,"line":460},39,[237,462,256],{"emptyLinePlaceholder":255},[237,464,466],{"class":239,"line":465},40,[237,467,468],{},"asyncio.run(main())\n",[237,470,472],{"class":239,"line":471},41,[237,473,256],{"emptyLinePlaceholder":255},[237,475,477],{"class":239,"line":476},42,[237,478,256],{"emptyLinePlaceholder":255},[237,480,482],{"class":239,"line":481},43,[237,483,484],{},"# --- 4. Let autospec choose per attribute: sync stays Mock\u002FMagicMock,\n",[237,486,488],{"class":239,"line":487},44,[237,489,490],{},"#        coroutine functions become AsyncMock automatically. ---\n",[237,492,494],{"class":239,"line":493},45,[237,495,496],{},"class Mixed:\n",[237,498,500],{"class":239,"line":499},46,[237,501,502],{},"    def sync_op(self) -> int: ...\n",[237,504,506],{"class":239,"line":505},47,[237,507,508],{},"    async def async_op(self) -> int: ...\n",[237,510,512],{"class":239,"line":511},48,[237,513,256],{"emptyLinePlaceholder":255},[237,515,517],{"class":239,"line":516},49,[237,518,519],{},"m = create_autospec(Mixed)\n",[237,521,523],{"class":239,"line":522},50,[237,524,525],{},"assert not asyncio.iscoroutinefunction(m.sync_op)\n",[237,527,529],{"class":239,"line":528},51,[237,530,531],{},"assert asyncio.iscoroutinefunction(m.async_op)   # picked AsyncMock for you\n",[51,533,535],{"id":534},"why-this-works","Why this works",[10,537,538,539,541,542,544,545,547,548,43,551,554,555,557,558,561,562,565,566,569,570,573,574,577,578,581],{},"The three classes are a subclass chain where each adds capability: ",[14,540,16],{}," records calls and auto-creates child attributes, ",[14,543,28],{}," additionally pre-configures the magic methods that protocols like ",[14,546,24],{},", ",[14,549,550],{},"for",[14,552,553],{},"len()"," invoke, and ",[14,556,36],{}," overrides ",[14,559,560],{},"__call__"," to return a coroutine so ",[14,563,564],{},"await mock()"," resolves and ",[14,567,568],{},"assert_awaited*"," helpers track it. Because ",[14,571,572],{},"create_autospec"," and ",[14,575,576],{},"autospec=True"," inspect each attribute with ",[14,579,580],{},"asyncio.iscoroutinefunction",", they substitute the correct class per member against the real signature — which is why autospec is the safest default in mixed sync\u002Fasync code.",[51,583,585],{"id":584},"edge-cases-and-failure-modes","Edge cases and failure modes",[56,587,588,608,623,648,666],{},[59,589,590,598,599,602,603,605,606,597],{},[591,592,593,594,597],"strong",{},"Awaiting a MagicMock raises ",[14,595,596],{},"TypeError","."," ",[14,600,601],{},"await magic_mock()"," fails because the call returns a plain ",[14,604,28],{},", not an awaitable. Switch the double — or the specific attribute — to ",[14,607,36],{},[59,609,610,615,616,618,619,597],{},[591,611,612,614],{},[14,613,36],{}," for a sync function over-wraps the call."," Calling a sync dependency backed by ",[14,617,36],{}," returns an unawaited coroutine; the real call site never awaits it, so the value is lost and you get a \"coroutine was never awaited\" warning. Mirror the real signature, ideally via autospec. This overlaps with debugging ",[83,620,622],{"href":621},"\u002Fsystematic-debugging-performance-profiling\u002Fdebugging-async-code-and-event-loops\u002Ftracing-unawaited-coroutine-warnings\u002F","tracing \"coroutine was never awaited\" warnings",[59,624,625,634,635,77,638,641,642,644,645,647],{},[591,626,627,628,630,631,633],{},"A bare ",[14,629,16],{}," cannot enter a ",[14,632,24],{}," block or be iterated."," It has no ",[14,636,637],{},"__enter__",[14,639,640],{},"__iter__",". Use ",[14,643,28],{},", or manually attach the dunder methods if you specifically want ",[14,646,16],{},"'s leaner surface.",[59,649,650,598,656,659,660,662,663,665],{},[591,651,652,655],{},[14,653,654],{},"spec"," does not change the call's await behaviour.",[14,657,658],{},"Mock(spec=AsyncClient)"," still returns sync values; ",[14,661,654],{}," constrains the attribute surface but not the call protocol. For awaitables you need ",[14,664,36],{}," (or autospec, which selects it).",[59,667,668,598,671,573,674,677,678,547,680,683,684,688,689,692,693,696,697,701],{},[591,669,670],{},"Mixing assertion families.",[14,672,673],{},"assert_called_*",[14,675,676],{},"assert_awaited_*"," are not interchangeable: on an ",[14,679,36],{},[14,681,682],{},"assert_called_once"," passes once the coroutine is ",[685,686,687],"em",{},"created",", while ",[14,690,691],{},"assert_awaited_once"," requires it to have been ",[685,694,695],{},"awaited",". Choose the await-aware variant for coroutine doubles. When configuring return values across these, the rules in ",[83,698,700],{"href":699},"\u002Fadvanced-mocking-test-doubles-in-python\u002Fautospec-strict-mocking\u002Fresolving-side_effect-and-return_value-conflicts\u002F","resolving side_effect and return_value conflicts"," apply unchanged.",[51,703,705],{"id":704},"frequently-asked-questions","Frequently Asked Questions",[10,707,708,711],{},[591,709,710],{},"When must I use AsyncMock instead of MagicMock?","\nUse AsyncMock whenever the code under test awaits the double. AsyncMock returns an awaitable on call so await mock() resolves; a MagicMock returns a plain value, so awaiting it raises TypeError: object MagicMock can't be used in await expression.",[10,713,714,717,718,573,721,724],{},[591,715,716],{},"Why does a bare Mock fail inside a with statement?","\nA with statement calls ",[591,719,720],{},"enter",[591,722,723],{},"exit",", which Mock does not pre-configure. MagicMock pre-wires the common dunder methods, so it works in with, for, and len contexts without manual setup.",[10,726,727,730],{},[591,728,729],{},"Does autospec pick the right mock class automatically?","\nYes. create_autospec and patch with autospec=True inspect each attribute and substitute AsyncMock for coroutine functions and MagicMock or Mock for the rest, so awaitables and dunder protocols are handled to match the real object.",[51,732,734],{"id":733},"related-guides","Related guides",[56,736,737,744,751,758],{},[59,738,739,740,597],{},"For the two-way comparison and performance notes, read ",[83,741,743],{"href":742},"\u002Fadvanced-mocking-test-doubles-in-python\u002Fdeep-dive-into-unittestmock\u002Fwhen-to-use-magicmock-vs-mock-in-python\u002F","When to Use MagicMock vs Mock in Python",[59,745,746,747,597],{},"Properties need special handling regardless of class — see ",[83,748,750],{"href":749},"\u002Fadvanced-mocking-test-doubles-in-python\u002Fautospec-strict-mocking\u002Fmocking-properties-and-class-attributes-with-autospec\u002F","mocking properties and class attributes with autospec",[59,752,753,754,597],{},"To bind any of these to a real interface, apply ",[83,755,757],{"href":756},"\u002Fadvanced-mocking-test-doubles-in-python\u002Fautospec-strict-mocking\u002F","autospec strict mocking",[59,759,760,761,597],{},"When a mock feels too brittle for stateful behaviour, weigh ",[83,762,764],{"href":763},"\u002Fadvanced-mocking-test-doubles-in-python\u002Fdependency-injection-for-testability\u002Finjecting-fakes-vs-mocks-in-constructors\u002F","injecting fakes vs mocks in constructors",[10,766,767,768],{},"← Back to ",[83,769,86],{"href":85},[771,772,773],"style",{},"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":233,"searchDepth":246,"depth":246,"links":775},[776,777,778,779,780,781],{"id":53,"depth":246,"text":54},{"id":222,"depth":246,"text":223},{"id":534,"depth":246,"text":535},{"id":584,"depth":246,"text":585},{"id":704,"depth":246,"text":705},{"id":733,"depth":246,"text":734},"Decide between Mock, MagicMock, and AsyncMock: dunder support, awaitable returns, autospec auto-selection, and the exact failure each one prevents in tests.","md",{"slug":785,"type":786,"breadcrumb":787,"datePublished":788,"dateModified":788,"faq":789,"howto":796},"mock-vs-magicmock-vs-asyncmock-when-to-use-each","long_tail","Mock vs MagicMock vs AsyncMock","2026-06-18",[790,792,794],{"q":710,"a":791},"Use AsyncMock whenever the code under test awaits the double. AsyncMock returns an awaitable on call so await mock() resolves; a MagicMock returns a plain value, so awaiting it raises TypeError: object MagicMock can't be used in await expression.",{"q":716,"a":793},"A with statement calls __enter__ and __exit__, which Mock does not pre-configure. MagicMock pre-wires the common dunder methods, so it works in with, for, and len contexts without manual setup.",{"q":729,"a":795},"Yes. create_autospec and patch with autospec=True inspect each attribute and substitute AsyncMock for coroutine functions and MagicMock or Mock for the rest, so awaitables and dunder protocols are handled to match the real object.",{"name":797,"description":798,"steps":799},"How to choose between Mock, MagicMock, and AsyncMock","Match the test double class to the protocol the code under test relies on: plain calls, dunder protocols, or await.",[800,803,806,809],{"name":801,"text":802},"Default to Mock with a spec","Use Mock(spec=Target) for plain method-and-attribute dependencies that need strict contract validation and minimal overhead.",{"name":804,"text":805},"Reach for MagicMock on protocol use","Use MagicMock when the code uses context managers, iteration, indexing, len, or arithmetic, since it pre-wires the dunder methods.",{"name":807,"text":808},"Use AsyncMock for awaited code","Use AsyncMock for any coroutine function or awaited attribute so await mock() resolves instead of raising TypeError.",{"name":810,"text":811},"Let autospec decide","Prefer create_autospec or autospec=True so the right class is chosen per attribute against the real signature.","\u002Fadvanced-mocking-test-doubles-in-python\u002Fdeep-dive-into-unittestmock\u002Fmock-vs-magicmock-vs-asyncmock-when-to-use-each",{"title":5,"description":782},"advanced-mocking-test-doubles-in-python\u002Fdeep-dive-into-unittestmock\u002Fmock-vs-magicmock-vs-asyncmock-when-to-use-each\u002Findex","AXyTuOdkhI7K5Qo4GGLTKNY60aZr5XIIIz8hQ4pbAME",1781793487880]