On Wednesday, December 12, 2012, Yang  wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">if I have mymodule.py:<div><br></div><div>class MyClass:</div><div>       def run():</div>
<div>             return 1</div><div><br></div><div><br></div><div><br></div><div>then I try to mock it in test:</div><div><br></div>

<div><br></div><div>with patch(&#39;mymodule.MyClass&#39;) as mock:</div><div>      instance = mock.return_value</div><div><br></div><div>      mock.run.return_value =2</div><div><br></div><div><br></div><div>this works fine. but if in my test code, I import the MyClass first:</div>


<div><br></div><div>from mymodule import MyClass</div><div><br></div><div>with patch(&#39;MyClass&#39;) as mock:</div><div> ......</div><div><br></div><div>it fails to find &#39;MyClass&#39;</div><div><br></div></blockquote>
<div><br></div><div>Correct. patch takes the fully qualified absolute name of an object (consider what would happen if it didn&#39;t, and you had an object and module with the same name, besides the fact that patch is a bit hard to grasp already without it searching locals first). If you want to patch objects in the current module, you&#39;d use &quot;mymodule.MyClass&quot; as you have above (or patch.object with the module object, which I prefer anyhow). That&#39;s almost certainly not what you want though, since your local scope is your testing module, when you need to be patching in the module under test.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><br></div><div>even more serious is that if I refer to the mock class with full name mymodule.Myclass in the patch() line, but the production code refers to it as simply Myclass after importing it first, the mock does not take effect,  so I have to modify production code to mock it out. this completely does not work for real testing cases.</div>
</blockquote><div><br></div><div>Mock isn&#39;t (too) magical. It just replaces names in the scope you tell it to. So if you have a name &quot;MyClass&quot; in mymodule, mock can patch that to refer to a different object if you patch in the correct location the correct name. Otherwise, it won&#39;t know what you&#39;re referring to.</div>
<div><br></div><div>You shouldn&#39;t have to modify production code certainly. The only way you&#39;d fail here presuming you patched in the right place (in mymodule as above) would be if some object already had / kept a reference to the real object by the time you patched, which shouldn&#39;t be happening under normal circumstances, but if it did you&#39;d want to patch that object&#39;s attr too.</div>
<div><br></div><div><br></div><div>Hope this helps,<span></span></div><div>Julian</div>