<div class="gmail_extra">Dear Tom and Herman,<br><br>Thank you guys for the genuine responses. They are helpful.<br><br>First, Herman:<br><br>&gt;In a script like the one you describe, I would try to group all the<br>
&gt; side-effecty IO related code into a single place and isolate it as<br>
&gt; much as possible from the logic of the rest of the program. That way,<br>
&gt; if you provide a single entry point or a wrapper for the IO code, you<br>
&gt; will be able to easily test the flow of the program and not have to<br>
&gt; worry about complicated mocking of built-in functions.<br><br>I am guessing you want me to create a small function that handles the logics inside the for loop (or iteritems())? <br><br><br>&gt;       for src, dest in src_dest:<br>
&gt;         if os.path.exists(src):<br>&gt;           if os.path.exists(dest):<br>&gt;              shutil.rmtree(dest)<br>&gt;           shutil.move(src, dest)   # either way we will proceed to move<br>
&gt;         else:<br>&gt;           return (False, &#39;%s does not exist!&#39; % src)<br>&gt;       return (True, &#39;Success!&#39;)<br><br>By skipping, yes, I want the &quot;else&quot; clause of `if os.path.exists(dest)` (meaning, it doesn&#39;t exist yet). By mocking &quot;os.path.exists&quot; to be True, it probably will make it True throughout. In that one special test, how can I separate the patch? How can I stop the patch at a particular point? <br>
<br>&gt; Finally, instead of using the exception system you are<br>
&gt; bulk-catching exceptions and returning error indicators instead. As you<br>&gt; mentioned above, this gives you the annoying requirement of figuring out every<br>
&gt; possible exception instead of leaving it to the caller to properly handle them.<br><br>I don&#39;t want to raise any exception, that&#39;s why I returns a tuple (False, e). As a web app, rasie exception is bad. I figure it&#39;s a good idea to just return False, along with the exception indicator. It&#39;s up to the user (in this case, at the moment, me) to log that exception, and return nice error message. <br>
<br>I think you are referring to `side_effect` which I think I need to explicitly supply the actual exception, right? Is there a more general way to do the side effect (I wouldn&#39;t know all the exceptions that the method is capable of generating)?<br>
<br>I think I can do this<br><br><div style="margin-left:40px">import unittest<br>from shutil import Error<br>import shutil<br>from mock import patch<br><br>class TestSequenceFunctions(unittest.TestCase):<br>    @patch.object(shutil, &#39;move&#39;)<br>
    def test2(self, mocker):<br>        import shutil<br>        mocker.side_effect = Error<br>        # mocker.side_effect = Exception  &lt;--- this is fine too<br>        src = &#39;/home/ted/tester/1&#39;<br>        dest = &#39;/home/ted/tester/2&#39;<br>
        #result = shutil.move(src, dest)<br>        #mocker.assert_called_with(src, dest)<br>        self.assertRaises(Error, mocker, src, dest)    # we can assert Exception instead of Error as well<br>        <br>So what&#39;s the downside of always using `Exception` over explicit exception class such as shutill.Error? My implementation catches `Exception` so I feel like I&#39;ve generalised it (Error will be caught as well).<br>
<br></div><br>Last, but not the least, mock objects supposed to mimic all the real thing, but it doesn&#39;t actually catch exception unless we supply a side-effect? I tried to minix `shutil.move(src, dest)` with dest being a directory that already exists. The real object will throw exception because dest must not already exists.<br>
<br><br>Thanks.<br><br>Ted<br><br><br><br><br><div class="gmail_quote">On Mon, Apr 23, 2012 at 10:47 PM, Tom Davis <span dir="ltr">&lt;<a href="mailto:tom@recursivedream.com" target="_blank">tom@recursivedream.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Mon, 23 Apr 2012 18:24:49 -0400, Tu Ted wrote:<br>
&gt; Please bear with me. Suppose I want to assert that result is in a<br>
&gt; particular format, I might set the return value to something as (True,<br>
&gt; &#39;Success&#39;)<br>
&gt;<br>
&gt; Sample code: <a href="http://pastebin.com/VraxaKjL" target="_blank">http://pastebin.com/VraxaKjL</a><br>
&gt;<br>
&gt; def batch_move(self, *args, **kwargs):<br>
&gt;   &#39;&#39;&#39;<br>
&gt;   Move a batch of files to its respective destinations.<br>
&gt;   Return type: tuple (boolean, message)<br>
&gt;                       T/F    , &#39;string&#39; / str(exception)<br>
&gt;   &#39;&#39;&#39;<br>
&gt;<br>
&gt;   srcs= kwargs.get(&#39;srcs&#39;, None)<br>
&gt;   dests = kwargs.get(&#39;dests&#39;, None)<br>
&gt;<br>
&gt;   try:<br>
&gt;     if srcs and dests:<br>
&gt;        # map srcs and dests into dictionary (srcs --&gt; keys, dests --&gt;<br>
&gt; values)<br>
&gt;        src_dest= dict(zip(srcs, dests))<br>
&gt;<br>
&gt;        for src, dest in src_dest:<br>
&gt;          if os.path.exists(src):<br>
&gt;            if os.path.exists(dest):<br>
&gt;               shutil.rmtree(dest)<br>
&gt;            shutil.move(src, dest)   # either way we will proceed to move<br>
&gt;          else:<br>
&gt;            return (False, &#39;%s does not exist!&#39; % src)<br>
&gt;        return (True, &#39;Success!&#39;)<br>
&gt;<br>
&gt;     else:<br>
&gt;        return (False, &#39;Something gone wrong with those kwargs...&#39;)<br>
&gt;   except Exception as e:<br>
&gt;     return (False, e)<br>
<br>
</div></div>I think you probably need src_dest.iteritems(), for starters...<br>
<div class="im"><br>
&gt;<br>
&gt; In order to get to return (True, &#39;Success!&#39;), I have<br>
&gt;<br>
&gt; 1. patch os.path.exists with True as return value. But in one unittest I<br>
&gt; want to skip this, how do I patch that os.path.exists?<br>
&gt;         if os.path.exists(dest):  # I want to skip this<br>
&gt;              shutil.rmtree(dest)<br>
&gt;<br>
<br>
</div>If by &quot;skip&quot; you mean go to the &quot;else&quot; block, you could just configure the mock<br>
to return False instead. If by &quot;skip&quot; you mean you want the actual function to<br>
be called, just don&#39;t mock that test (if using a decorator) or stop the patch<br>
(if patching manually).<br>
<div class="im"><br>
&gt;<br>
&gt;<br>
&gt; 2. How do I patch shutil.move(src, dest)? Do I just give True so it doesn&#39;t<br>
&gt; generate error? What if I want the case it fails and caught an exception?<br>
&gt; How do I simulate that? (I wouldn&#39;t always know which exception to catch,<br>
&gt; the primarily reason to use Exception as e).<br>
<br>
</div>You should test every case, both success and failure. You can consult the<br>
documentation or the source for `shutil.move` in order to write tests for each<br>
failure case. In the case that neither of these are completely helpful, just try<br>
different scenarios and see what happens. Why would moves fail? Destination<br>
exists, insufficient permissions, etc.<br>
<div class="im"><br>
&gt;<br>
&gt; 3. If I actually pass the function, does it really mean no exception caught<br>
&gt; and it went through every single line? Or is it because I set<br>
&gt; `mock_object.return_value = (True, &#39;Success!&#39;)?<br>
<br>
</div>A library like coverage.py will tell you that more easily, but if all you did<br>
was mock exists() and move(), then you could get every other line to run<br>
(presuming you had True/False cases that ultimately cover every code path).<br>
<br>
Now, there are a number of ways you&#39;re making your life more difficult by the<br>
way this function is written. First, it has to validate its arguments manually;<br>
that adds another code path (bad kwargs). Second, it couples the success of the<br>
function with the presentation of its failure; this could lead you to test<br>
oft-altered string values (which probably have no place in this function to<br>
begin with). Finally, instead of using the exception system you are<br>
bulk-catching exceptions and returning error indicators instead. As you<br>
mentioned above, this gives you the annoying requirement of figuring out every<br>
possible exception instead of leaving it to the caller to properly handle them.<br>
<div class="im"><br>
&gt;<br>
&gt; 4. I am only using two dependencies here, do I need to patch out all the<br>
&gt; external dependencies such as (os, sys, math, datetime) all in one? Or if<br>
&gt; my function is using other functions (which are refactored)<br>
&gt;<br>
&gt;<br>
&gt;  def f1(*args, **kwargs):<br>
&gt;     f2(..)   # use math, plot, datetime<br>
&gt;     f3(..)   # use math and datetime<br>
&gt;     f4(..)   # use datetime<br>
<br>
</div>You only need to patch that which you do not want to run as normal. In the<br>
example you gave, you should technically mock calls to each of f2(), f3(), and<br>
f4(), simply asserting on the values passed to them. This, of course, presumes<br>
you have written tests for each of these functions elsewhere, thus do not need<br>
to test them indirectly a second time.<br>
<div class="im"><br>
&gt;<br>
&gt;<br>
&gt; Thanks. Sorry for the long questions. I really want to be good at writing<br>
&gt; unittests.<br>
<br>
</div>An excellent goal to those on this list, I am sure ;)<br>
<br>
Hopefully my answers were somewhat useful...<br>
<br>
&gt;<br>
&gt;<br>
&gt; --<br>
&gt; Ted<br>
<br>
&gt; _______________________________________________<br>
&gt; testing-in-python mailing list<br>
&gt; <a href="mailto:testing-in-python@lists.idyll.org">testing-in-python@lists.idyll.org</a><br>
&gt; <a href="http://lists.idyll.org/listinfo/testing-in-python" target="_blank">http://lists.idyll.org/listinfo/testing-in-python</a><br>
<br>
<br>
_______________________________________________<br>
testing-in-python mailing list<br>
<a href="mailto:testing-in-python@lists.idyll.org">testing-in-python@lists.idyll.org</a><br>
<a href="http://lists.idyll.org/listinfo/testing-in-python" target="_blank">http://lists.idyll.org/listinfo/testing-in-python</a><br>
</blockquote></div><br></div>