Wed, 31 Dec 2014 06:55:50 +0100
Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2
michael@0 | 1 | |
michael@0 | 2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" |
michael@0 | 3 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
michael@0 | 4 | |
michael@0 | 5 | |
michael@0 | 6 | <html xmlns="http://www.w3.org/1999/xhtml"> |
michael@0 | 7 | <head> |
michael@0 | 8 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
michael@0 | 9 | |
michael@0 | 10 | <title>Further Examples — Mock 1.0.0 documentation</title> |
michael@0 | 11 | |
michael@0 | 12 | <link rel="stylesheet" href="_static/nature.css" type="text/css" /> |
michael@0 | 13 | <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> |
michael@0 | 14 | |
michael@0 | 15 | <script type="text/javascript"> |
michael@0 | 16 | var DOCUMENTATION_OPTIONS = { |
michael@0 | 17 | URL_ROOT: '', |
michael@0 | 18 | VERSION: '1.0.0', |
michael@0 | 19 | COLLAPSE_INDEX: false, |
michael@0 | 20 | FILE_SUFFIX: '.html', |
michael@0 | 21 | HAS_SOURCE: true |
michael@0 | 22 | }; |
michael@0 | 23 | </script> |
michael@0 | 24 | <script type="text/javascript" src="_static/jquery.js"></script> |
michael@0 | 25 | <script type="text/javascript" src="_static/underscore.js"></script> |
michael@0 | 26 | <script type="text/javascript" src="_static/doctools.js"></script> |
michael@0 | 27 | <link rel="top" title="Mock 1.0.0 documentation" href="index.html" /> |
michael@0 | 28 | <link rel="next" title="Mock Library Comparison" href="compare.html" /> |
michael@0 | 29 | <link rel="prev" title="Getting Started with Mock" href="getting-started.html" /> |
michael@0 | 30 | </head> |
michael@0 | 31 | <body> |
michael@0 | 32 | <div class="related"> |
michael@0 | 33 | <h3>Navigation</h3> |
michael@0 | 34 | <ul> |
michael@0 | 35 | <li class="right" style="margin-right: 10px"> |
michael@0 | 36 | <a href="genindex.html" title="General Index" |
michael@0 | 37 | accesskey="I">index</a></li> |
michael@0 | 38 | <li class="right" > |
michael@0 | 39 | <a href="compare.html" title="Mock Library Comparison" |
michael@0 | 40 | accesskey="N">next</a> |</li> |
michael@0 | 41 | <li class="right" > |
michael@0 | 42 | <a href="getting-started.html" title="Getting Started with Mock" |
michael@0 | 43 | accesskey="P">previous</a> |</li> |
michael@0 | 44 | <li><a href="index.html">Mock 1.0.0 documentation</a> »</li> |
michael@0 | 45 | </ul> |
michael@0 | 46 | </div> |
michael@0 | 47 | |
michael@0 | 48 | <div class="document"> |
michael@0 | 49 | <div class="documentwrapper"> |
michael@0 | 50 | <div class="bodywrapper"> |
michael@0 | 51 | <div class="body"> |
michael@0 | 52 | |
michael@0 | 53 | <div class="section" id="further-examples"> |
michael@0 | 54 | <span id="id1"></span><h1>Further Examples<a class="headerlink" href="#further-examples" title="Permalink to this headline">¶</a></h1> |
michael@0 | 55 | <p>For comprehensive examples, see the unit tests included in the full source |
michael@0 | 56 | distribution.</p> |
michael@0 | 57 | <p>Here are some more examples for some slightly more advanced scenarios than in |
michael@0 | 58 | the <a class="reference internal" href="getting-started.html#getting-started"><em>getting started</em></a> guide.</p> |
michael@0 | 59 | <div class="section" id="mocking-chained-calls"> |
michael@0 | 60 | <h2>Mocking chained calls<a class="headerlink" href="#mocking-chained-calls" title="Permalink to this headline">¶</a></h2> |
michael@0 | 61 | <p>Mocking chained calls is actually straightforward with mock once you |
michael@0 | 62 | understand the <a class="reference internal" href="mock.html#mock.Mock.return_value" title="mock.Mock.return_value"><tt class="xref py py-attr docutils literal"><span class="pre">return_value</span></tt></a> attribute. When a mock is called for |
michael@0 | 63 | the first time, or you fetch its <cite>return_value</cite> before it has been called, a |
michael@0 | 64 | new <cite>Mock</cite> is created.</p> |
michael@0 | 65 | <p>This means that you can see how the object returned from a call to a mocked |
michael@0 | 66 | object has been used by interrogating the <cite>return_value</cite> mock:</p> |
michael@0 | 67 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">mock</span> <span class="o">=</span> <span class="n">Mock</span><span class="p">()</span> |
michael@0 | 68 | <span class="gp">>>> </span><span class="n">mock</span><span class="p">()</span><span class="o">.</span><span class="n">foo</span><span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="n">b</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span> |
michael@0 | 69 | <span class="go"><Mock name='mock().foo()' id='...'></span> |
michael@0 | 70 | <span class="gp">>>> </span><span class="n">mock</span><span class="o">.</span><span class="n">return_value</span><span class="o">.</span><span class="n">foo</span><span class="o">.</span><span class="n">assert_called_with</span><span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="n">b</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span> |
michael@0 | 71 | </pre></div> |
michael@0 | 72 | </div> |
michael@0 | 73 | <p>From here it is a simple step to configure and then make assertions about |
michael@0 | 74 | chained calls. Of course another alternative is writing your code in a more |
michael@0 | 75 | testable way in the first place...</p> |
michael@0 | 76 | <p>So, suppose we have some code that looks a little bit like this:</p> |
michael@0 | 77 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="k">class</span> <span class="nc">Something</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> |
michael@0 | 78 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
michael@0 | 79 | <span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">backend</span> <span class="o">=</span> <span class="n">BackendProvider</span><span class="p">()</span> |
michael@0 | 80 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">method</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
michael@0 | 81 | <span class="gp">... </span> <span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">backend</span><span class="o">.</span><span class="n">get_endpoint</span><span class="p">(</span><span class="s">'foobar'</span><span class="p">)</span><span class="o">.</span><span class="n">create_call</span><span class="p">(</span><span class="s">'spam'</span><span class="p">,</span> <span class="s">'eggs'</span><span class="p">)</span><span class="o">.</span><span class="n">start_call</span><span class="p">()</span> |
michael@0 | 82 | <span class="gp">... </span> <span class="c"># more code</span> |
michael@0 | 83 | </pre></div> |
michael@0 | 84 | </div> |
michael@0 | 85 | <p>Assuming that <cite>BackendProvider</cite> is already well tested, how do we test |
michael@0 | 86 | <cite>method()</cite>? Specifically, we want to test that the code section <cite># more |
michael@0 | 87 | code</cite> uses the response object in the correct way.</p> |
michael@0 | 88 | <p>As this chain of calls is made from an instance attribute we can monkey patch |
michael@0 | 89 | the <cite>backend</cite> attribute on a <cite>Something</cite> instance. In this particular case |
michael@0 | 90 | we are only interested in the return value from the final call to |
michael@0 | 91 | <cite>start_call</cite> so we don’t have much configuration to do. Let’s assume the |
michael@0 | 92 | object it returns is ‘file-like’, so we’ll ensure that our response object |
michael@0 | 93 | uses the builtin <cite>file</cite> as its <cite>spec</cite>.</p> |
michael@0 | 94 | <p>To do this we create a mock instance as our mock backend and create a mock |
michael@0 | 95 | response object for it. To set the response as the return value for that final |
michael@0 | 96 | <cite>start_call</cite> we could do this:</p> |
michael@0 | 97 | <blockquote> |
michael@0 | 98 | <div><cite>mock_backend.get_endpoint.return_value.create_call.return_value.start_call.return_value = mock_response</cite>.</div></blockquote> |
michael@0 | 99 | <p>We can do that in a slightly nicer way using the <a class="reference internal" href="mock.html#mock.Mock.configure_mock" title="mock.Mock.configure_mock"><tt class="xref py py-meth docutils literal"><span class="pre">configure_mock()</span></tt></a> |
michael@0 | 100 | method to directly set the return value for us:</p> |
michael@0 | 101 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">something</span> <span class="o">=</span> <span class="n">Something</span><span class="p">()</span> |
michael@0 | 102 | <span class="gp">>>> </span><span class="n">mock_response</span> <span class="o">=</span> <span class="n">Mock</span><span class="p">(</span><span class="n">spec</span><span class="o">=</span><span class="nb">file</span><span class="p">)</span> |
michael@0 | 103 | <span class="gp">>>> </span><span class="n">mock_backend</span> <span class="o">=</span> <span class="n">Mock</span><span class="p">()</span> |
michael@0 | 104 | <span class="gp">>>> </span><span class="n">config</span> <span class="o">=</span> <span class="p">{</span><span class="s">'get_endpoint.return_value.create_call.return_value.start_call.return_value'</span><span class="p">:</span> <span class="n">mock_response</span><span class="p">}</span> |
michael@0 | 105 | <span class="gp">>>> </span><span class="n">mock_backend</span><span class="o">.</span><span class="n">configure_mock</span><span class="p">(</span><span class="o">**</span><span class="n">config</span><span class="p">)</span> |
michael@0 | 106 | </pre></div> |
michael@0 | 107 | </div> |
michael@0 | 108 | <p>With these we monkey patch the “mock backend” in place and can make the real |
michael@0 | 109 | call:</p> |
michael@0 | 110 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">something</span><span class="o">.</span><span class="n">backend</span> <span class="o">=</span> <span class="n">mock_backend</span> |
michael@0 | 111 | <span class="gp">>>> </span><span class="n">something</span><span class="o">.</span><span class="n">method</span><span class="p">()</span> |
michael@0 | 112 | </pre></div> |
michael@0 | 113 | </div> |
michael@0 | 114 | <p>Using <a class="reference internal" href="mock.html#mock.Mock.mock_calls" title="mock.Mock.mock_calls"><tt class="xref py py-attr docutils literal"><span class="pre">mock_calls</span></tt></a> we can check the chained call with a single |
michael@0 | 115 | assert. A chained call is several calls in one line of code, so there will be |
michael@0 | 116 | several entries in <cite>mock_calls</cite>. We can use <a class="reference internal" href="helpers.html#mock.call.call_list" title="mock.call.call_list"><tt class="xref py py-meth docutils literal"><span class="pre">call.call_list()</span></tt></a> to create |
michael@0 | 117 | this list of calls for us:</p> |
michael@0 | 118 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">chained</span> <span class="o">=</span> <span class="n">call</span><span class="o">.</span><span class="n">get_endpoint</span><span class="p">(</span><span class="s">'foobar'</span><span class="p">)</span><span class="o">.</span><span class="n">create_call</span><span class="p">(</span><span class="s">'spam'</span><span class="p">,</span> <span class="s">'eggs'</span><span class="p">)</span><span class="o">.</span><span class="n">start_call</span><span class="p">()</span> |
michael@0 | 119 | <span class="gp">>>> </span><span class="n">call_list</span> <span class="o">=</span> <span class="n">chained</span><span class="o">.</span><span class="n">call_list</span><span class="p">()</span> |
michael@0 | 120 | <span class="gp">>>> </span><span class="k">assert</span> <span class="n">mock_backend</span><span class="o">.</span><span class="n">mock_calls</span> <span class="o">==</span> <span class="n">call_list</span> |
michael@0 | 121 | </pre></div> |
michael@0 | 122 | </div> |
michael@0 | 123 | </div> |
michael@0 | 124 | <div class="section" id="partial-mocking"> |
michael@0 | 125 | <h2>Partial mocking<a class="headerlink" href="#partial-mocking" title="Permalink to this headline">¶</a></h2> |
michael@0 | 126 | <p>In some tests I wanted to mock out a call to <a class="reference external" href="http://docs.python.org/library/datetime.html#datetime.date.today">datetime.date.today()</a> to return |
michael@0 | 127 | a known date, but I didn’t want to prevent the code under test from |
michael@0 | 128 | creating new date objects. Unfortunately <cite>datetime.date</cite> is written in C, and |
michael@0 | 129 | so I couldn’t just monkey-patch out the static <cite>date.today</cite> method.</p> |
michael@0 | 130 | <p>I found a simple way of doing this that involved effectively wrapping the date |
michael@0 | 131 | class with a mock, but passing through calls to the constructor to the real |
michael@0 | 132 | class (and returning real instances).</p> |
michael@0 | 133 | <p>The <a class="reference internal" href="patch.html#mock.patch" title="mock.patch"><tt class="xref py py-func docutils literal"><span class="pre">patch</span> <span class="pre">decorator</span></tt></a> is used here to |
michael@0 | 134 | mock out the <cite>date</cite> class in the module under test. The <tt class="xref py py-attr docutils literal"><span class="pre">side_effect</span></tt> |
michael@0 | 135 | attribute on the mock date class is then set to a lambda function that returns |
michael@0 | 136 | a real date. When the mock date class is called a real date will be |
michael@0 | 137 | constructed and returned by <cite>side_effect</cite>.</p> |
michael@0 | 138 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">date</span> |
michael@0 | 139 | <span class="gp">>>> </span><span class="k">with</span> <span class="n">patch</span><span class="p">(</span><span class="s">'mymodule.date'</span><span class="p">)</span> <span class="k">as</span> <span class="n">mock_date</span><span class="p">:</span> |
michael@0 | 140 | <span class="gp">... </span> <span class="n">mock_date</span><span class="o">.</span><span class="n">today</span><span class="o">.</span><span class="n">return_value</span> <span class="o">=</span> <span class="n">date</span><span class="p">(</span><span class="mi">2010</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">8</span><span class="p">)</span> |
michael@0 | 141 | <span class="gp">... </span> <span class="n">mock_date</span><span class="o">.</span><span class="n">side_effect</span> <span class="o">=</span> <span class="k">lambda</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">:</span> <span class="n">date</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">)</span> |
michael@0 | 142 | <span class="gp">...</span> |
michael@0 | 143 | <span class="gp">... </span> <span class="k">assert</span> <span class="n">mymodule</span><span class="o">.</span><span class="n">date</span><span class="o">.</span><span class="n">today</span><span class="p">()</span> <span class="o">==</span> <span class="n">date</span><span class="p">(</span><span class="mi">2010</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">8</span><span class="p">)</span> |
michael@0 | 144 | <span class="gp">... </span> <span class="k">assert</span> <span class="n">mymodule</span><span class="o">.</span><span class="n">date</span><span class="p">(</span><span class="mi">2009</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">8</span><span class="p">)</span> <span class="o">==</span> <span class="n">date</span><span class="p">(</span><span class="mi">2009</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">8</span><span class="p">)</span> |
michael@0 | 145 | <span class="gp">...</span> |
michael@0 | 146 | </pre></div> |
michael@0 | 147 | </div> |
michael@0 | 148 | <p>Note that we don’t patch <cite>datetime.date</cite> globally, we patch <cite>date</cite> in the |
michael@0 | 149 | module that <em>uses</em> it. See <a class="reference internal" href="patch.html#where-to-patch"><em>where to patch</em></a>.</p> |
michael@0 | 150 | <p>When <cite>date.today()</cite> is called a known date is returned, but calls to the |
michael@0 | 151 | <cite>date(...)</cite> constructor still return normal dates. Without this you can find |
michael@0 | 152 | yourself having to calculate an expected result using exactly the same |
michael@0 | 153 | algorithm as the code under test, which is a classic testing anti-pattern.</p> |
michael@0 | 154 | <p>Calls to the date constructor are recorded in the <cite>mock_date</cite> attributes |
michael@0 | 155 | (<cite>call_count</cite> and friends) which may also be useful for your tests.</p> |
michael@0 | 156 | <p>An alternative way of dealing with mocking dates, or other builtin classes, |
michael@0 | 157 | is discussed in <a class="reference external" href="http://williamjohnbert.com/2011/07/how-to-unit-testing-in-django-with-mocking-and-patching/">this blog entry</a>.</p> |
michael@0 | 158 | </div> |
michael@0 | 159 | <div class="section" id="mocking-a-generator-method"> |
michael@0 | 160 | <h2>Mocking a Generator Method<a class="headerlink" href="#mocking-a-generator-method" title="Permalink to this headline">¶</a></h2> |
michael@0 | 161 | <p>A Python generator is a function or method that uses the <a class="reference external" href="http://docs.python.org/reference/simple_stmts.html#the-yield-statement">yield statement</a> to |
michael@0 | 162 | return a series of values when iterated over <a class="footnote-reference" href="#id3" id="id2">[1]</a>.</p> |
michael@0 | 163 | <p>A generator method / function is called to return the generator object. It is |
michael@0 | 164 | the generator object that is then iterated over. The protocol method for |
michael@0 | 165 | iteration is <a class="reference external" href="http://docs.python.org/library/stdtypes.html#container.__iter__">__iter__</a>, so we can |
michael@0 | 166 | mock this using a <cite>MagicMock</cite>.</p> |
michael@0 | 167 | <p>Here’s an example class with an “iter” method implemented as a generator:</p> |
michael@0 | 168 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="k">class</span> <span class="nc">Foo</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> |
michael@0 | 169 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">iter</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
michael@0 | 170 | <span class="gp">... </span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]:</span> |
michael@0 | 171 | <span class="gp">... </span> <span class="k">yield</span> <span class="n">i</span> |
michael@0 | 172 | <span class="gp">...</span> |
michael@0 | 173 | <span class="gp">>>> </span><span class="n">foo</span> <span class="o">=</span> <span class="n">Foo</span><span class="p">()</span> |
michael@0 | 174 | <span class="gp">>>> </span><span class="nb">list</span><span class="p">(</span><span class="n">foo</span><span class="o">.</span><span class="n">iter</span><span class="p">())</span> |
michael@0 | 175 | <span class="go">[1, 2, 3]</span> |
michael@0 | 176 | </pre></div> |
michael@0 | 177 | </div> |
michael@0 | 178 | <p>How would we mock this class, and in particular its “iter” method?</p> |
michael@0 | 179 | <p>To configure the values returned from the iteration (implicit in the call to |
michael@0 | 180 | <cite>list</cite>), we need to configure the object returned by the call to <cite>foo.iter()</cite>.</p> |
michael@0 | 181 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">mock_foo</span> <span class="o">=</span> <span class="n">MagicMock</span><span class="p">()</span> |
michael@0 | 182 | <span class="gp">>>> </span><span class="n">mock_foo</span><span class="o">.</span><span class="n">iter</span><span class="o">.</span><span class="n">return_value</span> <span class="o">=</span> <span class="nb">iter</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">])</span> |
michael@0 | 183 | <span class="gp">>>> </span><span class="nb">list</span><span class="p">(</span><span class="n">mock_foo</span><span class="o">.</span><span class="n">iter</span><span class="p">())</span> |
michael@0 | 184 | <span class="go">[1, 2, 3]</span> |
michael@0 | 185 | </pre></div> |
michael@0 | 186 | </div> |
michael@0 | 187 | <table class="docutils footnote" frame="void" id="id3" rules="none"> |
michael@0 | 188 | <colgroup><col class="label" /><col /></colgroup> |
michael@0 | 189 | <tbody valign="top"> |
michael@0 | 190 | <tr><td class="label"><a class="fn-backref" href="#id2">[1]</a></td><td>There are also generator expressions and more <a class="reference external" href="http://www.dabeaz.com/coroutines/index.html">advanced uses</a> of generators, but we aren’t |
michael@0 | 191 | concerned about them here. A very good introduction to generators and how |
michael@0 | 192 | powerful they are is: <a class="reference external" href="http://www.dabeaz.com/generators/">Generator Tricks for Systems Programmers</a>.</td></tr> |
michael@0 | 193 | </tbody> |
michael@0 | 194 | </table> |
michael@0 | 195 | </div> |
michael@0 | 196 | <div class="section" id="applying-the-same-patch-to-every-test-method"> |
michael@0 | 197 | <h2>Applying the same patch to every test method<a class="headerlink" href="#applying-the-same-patch-to-every-test-method" title="Permalink to this headline">¶</a></h2> |
michael@0 | 198 | <p>If you want several patches in place for multiple test methods the obvious way |
michael@0 | 199 | is to apply the patch decorators to every method. This can feel like unnecessary |
michael@0 | 200 | repetition. For Python 2.6 or more recent you can use <cite>patch</cite> (in all its |
michael@0 | 201 | various forms) as a class decorator. This applies the patches to all test |
michael@0 | 202 | methods on the class. A test method is identified by methods whose names start |
michael@0 | 203 | with <cite>test</cite>:</p> |
michael@0 | 204 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="nd">@patch</span><span class="p">(</span><span class="s">'mymodule.SomeClass'</span><span class="p">)</span> |
michael@0 | 205 | <span class="gp">... </span><span class="k">class</span> <span class="nc">MyTest</span><span class="p">(</span><span class="n">TestCase</span><span class="p">):</span> |
michael@0 | 206 | <span class="gp">...</span> |
michael@0 | 207 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">test_one</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">MockSomeClass</span><span class="p">):</span> |
michael@0 | 208 | <span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">mymodule</span><span class="o">.</span><span class="n">SomeClass</span> <span class="ow">is</span> <span class="n">MockSomeClass</span><span class="p">)</span> |
michael@0 | 209 | <span class="gp">...</span> |
michael@0 | 210 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">test_two</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">MockSomeClass</span><span class="p">):</span> |
michael@0 | 211 | <span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">mymodule</span><span class="o">.</span><span class="n">SomeClass</span> <span class="ow">is</span> <span class="n">MockSomeClass</span><span class="p">)</span> |
michael@0 | 212 | <span class="gp">...</span> |
michael@0 | 213 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">not_a_test</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
michael@0 | 214 | <span class="gp">... </span> <span class="k">return</span> <span class="s">'something'</span> |
michael@0 | 215 | <span class="gp">...</span> |
michael@0 | 216 | <span class="gp">>>> </span><span class="n">MyTest</span><span class="p">(</span><span class="s">'test_one'</span><span class="p">)</span><span class="o">.</span><span class="n">test_one</span><span class="p">()</span> |
michael@0 | 217 | <span class="gp">>>> </span><span class="n">MyTest</span><span class="p">(</span><span class="s">'test_two'</span><span class="p">)</span><span class="o">.</span><span class="n">test_two</span><span class="p">()</span> |
michael@0 | 218 | <span class="gp">>>> </span><span class="n">MyTest</span><span class="p">(</span><span class="s">'test_two'</span><span class="p">)</span><span class="o">.</span><span class="n">not_a_test</span><span class="p">()</span> |
michael@0 | 219 | <span class="go">'something'</span> |
michael@0 | 220 | </pre></div> |
michael@0 | 221 | </div> |
michael@0 | 222 | <p>An alternative way of managing patches is to use the <a class="reference internal" href="patch.html#start-and-stop"><em>patch methods: start and stop</em></a>. |
michael@0 | 223 | These allow you to move the patching into your <cite>setUp</cite> and <cite>tearDown</cite> methods.</p> |
michael@0 | 224 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="k">class</span> <span class="nc">MyTest</span><span class="p">(</span><span class="n">TestCase</span><span class="p">):</span> |
michael@0 | 225 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">setUp</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
michael@0 | 226 | <span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">patcher</span> <span class="o">=</span> <span class="n">patch</span><span class="p">(</span><span class="s">'mymodule.foo'</span><span class="p">)</span> |
michael@0 | 227 | <span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">mock_foo</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">patcher</span><span class="o">.</span><span class="n">start</span><span class="p">()</span> |
michael@0 | 228 | <span class="gp">...</span> |
michael@0 | 229 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">test_foo</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
michael@0 | 230 | <span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">mymodule</span><span class="o">.</span><span class="n">foo</span> <span class="ow">is</span> <span class="bp">self</span><span class="o">.</span><span class="n">mock_foo</span><span class="p">)</span> |
michael@0 | 231 | <span class="gp">...</span> |
michael@0 | 232 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">tearDown</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
michael@0 | 233 | <span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">patcher</span><span class="o">.</span><span class="n">stop</span><span class="p">()</span> |
michael@0 | 234 | <span class="gp">...</span> |
michael@0 | 235 | <span class="gp">>>> </span><span class="n">MyTest</span><span class="p">(</span><span class="s">'test_foo'</span><span class="p">)</span><span class="o">.</span><span class="n">run</span><span class="p">()</span> |
michael@0 | 236 | </pre></div> |
michael@0 | 237 | </div> |
michael@0 | 238 | <p>If you use this technique you must ensure that the patching is “undone” by |
michael@0 | 239 | calling <cite>stop</cite>. This can be fiddlier than you might think, because if an |
michael@0 | 240 | exception is raised in the setUp then tearDown is not called. <a class="reference external" href="http://pypi.python.org/pypi/unittest2">unittest2</a> cleanup functions make this simpler:</p> |
michael@0 | 241 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="k">class</span> <span class="nc">MyTest</span><span class="p">(</span><span class="n">TestCase</span><span class="p">):</span> |
michael@0 | 242 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">setUp</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
michael@0 | 243 | <span class="gp">... </span> <span class="n">patcher</span> <span class="o">=</span> <span class="n">patch</span><span class="p">(</span><span class="s">'mymodule.foo'</span><span class="p">)</span> |
michael@0 | 244 | <span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">addCleanup</span><span class="p">(</span><span class="n">patcher</span><span class="o">.</span><span class="n">stop</span><span class="p">)</span> |
michael@0 | 245 | <span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">mock_foo</span> <span class="o">=</span> <span class="n">patcher</span><span class="o">.</span><span class="n">start</span><span class="p">()</span> |
michael@0 | 246 | <span class="gp">...</span> |
michael@0 | 247 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">test_foo</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
michael@0 | 248 | <span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">mymodule</span><span class="o">.</span><span class="n">foo</span> <span class="ow">is</span> <span class="bp">self</span><span class="o">.</span><span class="n">mock_foo</span><span class="p">)</span> |
michael@0 | 249 | <span class="gp">...</span> |
michael@0 | 250 | <span class="gp">>>> </span><span class="n">MyTest</span><span class="p">(</span><span class="s">'test_foo'</span><span class="p">)</span><span class="o">.</span><span class="n">run</span><span class="p">()</span> |
michael@0 | 251 | </pre></div> |
michael@0 | 252 | </div> |
michael@0 | 253 | </div> |
michael@0 | 254 | <div class="section" id="mocking-unbound-methods"> |
michael@0 | 255 | <h2>Mocking Unbound Methods<a class="headerlink" href="#mocking-unbound-methods" title="Permalink to this headline">¶</a></h2> |
michael@0 | 256 | <p>Whilst writing tests today I needed to patch an <em>unbound method</em> (patching the |
michael@0 | 257 | method on the class rather than on the instance). I needed self to be passed |
michael@0 | 258 | in as the first argument because I want to make asserts about which objects |
michael@0 | 259 | were calling this particular method. The issue is that you can’t patch with a |
michael@0 | 260 | mock for this, because if you replace an unbound method with a mock it doesn’t |
michael@0 | 261 | become a bound method when fetched from the instance, and so it doesn’t get |
michael@0 | 262 | self passed in. The workaround is to patch the unbound method with a real |
michael@0 | 263 | function instead. The <a class="reference internal" href="patch.html#mock.patch" title="mock.patch"><tt class="xref py py-func docutils literal"><span class="pre">patch()</span></tt></a> decorator makes it so simple to |
michael@0 | 264 | patch out methods with a mock that having to create a real function becomes a |
michael@0 | 265 | nuisance.</p> |
michael@0 | 266 | <p>If you pass <cite>autospec=True</cite> to patch then it does the patching with a |
michael@0 | 267 | <em>real</em> function object. This function object has the same signature as the one |
michael@0 | 268 | it is replacing, but delegates to a mock under the hood. You still get your |
michael@0 | 269 | mock auto-created in exactly the same way as before. What it means though, is |
michael@0 | 270 | that if you use it to patch out an unbound method on a class the mocked |
michael@0 | 271 | function will be turned into a bound method if it is fetched from an instance. |
michael@0 | 272 | It will have <cite>self</cite> passed in as the first argument, which is exactly what I |
michael@0 | 273 | wanted:</p> |
michael@0 | 274 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="k">class</span> <span class="nc">Foo</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> |
michael@0 | 275 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
michael@0 | 276 | <span class="gp">... </span> <span class="k">pass</span> |
michael@0 | 277 | <span class="gp">...</span> |
michael@0 | 278 | <span class="gp">>>> </span><span class="k">with</span> <span class="n">patch</span><span class="o">.</span><span class="n">object</span><span class="p">(</span><span class="n">Foo</span><span class="p">,</span> <span class="s">'foo'</span><span class="p">,</span> <span class="n">autospec</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span> <span class="k">as</span> <span class="n">mock_foo</span><span class="p">:</span> |
michael@0 | 279 | <span class="gp">... </span> <span class="n">mock_foo</span><span class="o">.</span><span class="n">return_value</span> <span class="o">=</span> <span class="s">'foo'</span> |
michael@0 | 280 | <span class="gp">... </span> <span class="n">foo</span> <span class="o">=</span> <span class="n">Foo</span><span class="p">()</span> |
michael@0 | 281 | <span class="gp">... </span> <span class="n">foo</span><span class="o">.</span><span class="n">foo</span><span class="p">()</span> |
michael@0 | 282 | <span class="gp">...</span> |
michael@0 | 283 | <span class="go">'foo'</span> |
michael@0 | 284 | <span class="gp">>>> </span><span class="n">mock_foo</span><span class="o">.</span><span class="n">assert_called_once_with</span><span class="p">(</span><span class="n">foo</span><span class="p">)</span> |
michael@0 | 285 | </pre></div> |
michael@0 | 286 | </div> |
michael@0 | 287 | <p>If we don’t use <cite>autospec=True</cite> then the unbound method is patched out |
michael@0 | 288 | with a Mock instance instead, and isn’t called with <cite>self</cite>.</p> |
michael@0 | 289 | </div> |
michael@0 | 290 | <div class="section" id="checking-multiple-calls-with-mock"> |
michael@0 | 291 | <h2>Checking multiple calls with mock<a class="headerlink" href="#checking-multiple-calls-with-mock" title="Permalink to this headline">¶</a></h2> |
michael@0 | 292 | <p>mock has a nice API for making assertions about how your mock objects are used.</p> |
michael@0 | 293 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">mock</span> <span class="o">=</span> <span class="n">Mock</span><span class="p">()</span> |
michael@0 | 294 | <span class="gp">>>> </span><span class="n">mock</span><span class="o">.</span><span class="n">foo_bar</span><span class="o">.</span><span class="n">return_value</span> <span class="o">=</span> <span class="bp">None</span> |
michael@0 | 295 | <span class="gp">>>> </span><span class="n">mock</span><span class="o">.</span><span class="n">foo_bar</span><span class="p">(</span><span class="s">'baz'</span><span class="p">,</span> <span class="n">spam</span><span class="o">=</span><span class="s">'eggs'</span><span class="p">)</span> |
michael@0 | 296 | <span class="gp">>>> </span><span class="n">mock</span><span class="o">.</span><span class="n">foo_bar</span><span class="o">.</span><span class="n">assert_called_with</span><span class="p">(</span><span class="s">'baz'</span><span class="p">,</span> <span class="n">spam</span><span class="o">=</span><span class="s">'eggs'</span><span class="p">)</span> |
michael@0 | 297 | </pre></div> |
michael@0 | 298 | </div> |
michael@0 | 299 | <p>If your mock is only being called once you can use the |
michael@0 | 300 | <tt class="xref py py-meth docutils literal"><span class="pre">assert_called_once_with()</span></tt> method that also asserts that the |
michael@0 | 301 | <tt class="xref py py-attr docutils literal"><span class="pre">call_count</span></tt> is one.</p> |
michael@0 | 302 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">mock</span><span class="o">.</span><span class="n">foo_bar</span><span class="o">.</span><span class="n">assert_called_once_with</span><span class="p">(</span><span class="s">'baz'</span><span class="p">,</span> <span class="n">spam</span><span class="o">=</span><span class="s">'eggs'</span><span class="p">)</span> |
michael@0 | 303 | <span class="gp">>>> </span><span class="n">mock</span><span class="o">.</span><span class="n">foo_bar</span><span class="p">()</span> |
michael@0 | 304 | <span class="gp">>>> </span><span class="n">mock</span><span class="o">.</span><span class="n">foo_bar</span><span class="o">.</span><span class="n">assert_called_once_with</span><span class="p">(</span><span class="s">'baz'</span><span class="p">,</span> <span class="n">spam</span><span class="o">=</span><span class="s">'eggs'</span><span class="p">)</span> |
michael@0 | 305 | <span class="gt">Traceback (most recent call last):</span> |
michael@0 | 306 | <span class="o">...</span> |
michael@0 | 307 | <span class="gr">AssertionError</span>: <span class="n">Expected to be called once. Called 2 times.</span> |
michael@0 | 308 | </pre></div> |
michael@0 | 309 | </div> |
michael@0 | 310 | <p>Both <cite>assert_called_with</cite> and <cite>assert_called_once_with</cite> make assertions about |
michael@0 | 311 | the <em>most recent</em> call. If your mock is going to be called several times, and |
michael@0 | 312 | you want to make assertions about <em>all</em> those calls you can use |
michael@0 | 313 | <a class="reference internal" href="mock.html#mock.Mock.call_args_list" title="mock.Mock.call_args_list"><tt class="xref py py-attr docutils literal"><span class="pre">call_args_list</span></tt></a>:</p> |
michael@0 | 314 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">mock</span> <span class="o">=</span> <span class="n">Mock</span><span class="p">(</span><span class="n">return_value</span><span class="o">=</span><span class="bp">None</span><span class="p">)</span> |
michael@0 | 315 | <span class="gp">>>> </span><span class="n">mock</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span> |
michael@0 | 316 | <span class="gp">>>> </span><span class="n">mock</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">)</span> |
michael@0 | 317 | <span class="gp">>>> </span><span class="n">mock</span><span class="p">()</span> |
michael@0 | 318 | <span class="gp">>>> </span><span class="n">mock</span><span class="o">.</span><span class="n">call_args_list</span> |
michael@0 | 319 | <span class="go">[call(1, 2, 3), call(4, 5, 6), call()]</span> |
michael@0 | 320 | </pre></div> |
michael@0 | 321 | </div> |
michael@0 | 322 | <p>The <a class="reference internal" href="helpers.html#mock.call" title="mock.call"><tt class="xref py py-data docutils literal"><span class="pre">call</span></tt></a> helper makes it easy to make assertions about these calls. You |
michael@0 | 323 | can build up a list of expected calls and compare it to <cite>call_args_list</cite>. This |
michael@0 | 324 | looks remarkably similar to the repr of the <cite>call_args_list</cite>:</p> |
michael@0 | 325 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">expected</span> <span class="o">=</span> <span class="p">[</span><span class="n">call</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="n">call</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">),</span> <span class="n">call</span><span class="p">()]</span> |
michael@0 | 326 | <span class="gp">>>> </span><span class="n">mock</span><span class="o">.</span><span class="n">call_args_list</span> <span class="o">==</span> <span class="n">expected</span> |
michael@0 | 327 | <span class="go">True</span> |
michael@0 | 328 | </pre></div> |
michael@0 | 329 | </div> |
michael@0 | 330 | </div> |
michael@0 | 331 | <div class="section" id="coping-with-mutable-arguments"> |
michael@0 | 332 | <h2>Coping with mutable arguments<a class="headerlink" href="#coping-with-mutable-arguments" title="Permalink to this headline">¶</a></h2> |
michael@0 | 333 | <p>Another situation is rare, but can bite you, is when your mock is called with |
michael@0 | 334 | mutable arguments. <cite>call_args</cite> and <cite>call_args_list</cite> store <em>references</em> to the |
michael@0 | 335 | arguments. If the arguments are mutated by the code under test then you can no |
michael@0 | 336 | longer make assertions about what the values were when the mock was called.</p> |
michael@0 | 337 | <p>Here’s some example code that shows the problem. Imagine the following functions |
michael@0 | 338 | defined in ‘mymodule’:</p> |
michael@0 | 339 | <div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">frob</span><span class="p">(</span><span class="n">val</span><span class="p">):</span> |
michael@0 | 340 | <span class="k">pass</span> |
michael@0 | 341 | |
michael@0 | 342 | <span class="k">def</span> <span class="nf">grob</span><span class="p">(</span><span class="n">val</span><span class="p">):</span> |
michael@0 | 343 | <span class="s">"First frob and then clear val"</span> |
michael@0 | 344 | <span class="n">frob</span><span class="p">(</span><span class="n">val</span><span class="p">)</span> |
michael@0 | 345 | <span class="n">val</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span> |
michael@0 | 346 | </pre></div> |
michael@0 | 347 | </div> |
michael@0 | 348 | <p>When we try to test that <cite>grob</cite> calls <cite>frob</cite> with the correct argument look |
michael@0 | 349 | what happens:</p> |
michael@0 | 350 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="k">with</span> <span class="n">patch</span><span class="p">(</span><span class="s">'mymodule.frob'</span><span class="p">)</span> <span class="k">as</span> <span class="n">mock_frob</span><span class="p">:</span> |
michael@0 | 351 | <span class="gp">... </span> <span class="n">val</span> <span class="o">=</span> <span class="nb">set</span><span class="p">([</span><span class="mi">6</span><span class="p">])</span> |
michael@0 | 352 | <span class="gp">... </span> <span class="n">mymodule</span><span class="o">.</span><span class="n">grob</span><span class="p">(</span><span class="n">val</span><span class="p">)</span> |
michael@0 | 353 | <span class="gp">...</span> |
michael@0 | 354 | <span class="gp">>>> </span><span class="n">val</span> |
michael@0 | 355 | <span class="go">set([])</span> |
michael@0 | 356 | <span class="gp">>>> </span><span class="n">mock_frob</span><span class="o">.</span><span class="n">assert_called_with</span><span class="p">(</span><span class="nb">set</span><span class="p">([</span><span class="mi">6</span><span class="p">]))</span> |
michael@0 | 357 | <span class="gt">Traceback (most recent call last):</span> |
michael@0 | 358 | <span class="o">...</span> |
michael@0 | 359 | <span class="gr">AssertionError: Expected</span>: <span class="n">((set([6]),), {})</span> |
michael@0 | 360 | <span class="go">Called with: ((set([]),), {})</span> |
michael@0 | 361 | </pre></div> |
michael@0 | 362 | </div> |
michael@0 | 363 | <p>One possibility would be for mock to copy the arguments you pass in. This |
michael@0 | 364 | could then cause problems if you do assertions that rely on object identity |
michael@0 | 365 | for equality.</p> |
michael@0 | 366 | <p>Here’s one solution that uses the <tt class="xref py py-attr docutils literal"><span class="pre">side_effect</span></tt> |
michael@0 | 367 | functionality. If you provide a <cite>side_effect</cite> function for a mock then |
michael@0 | 368 | <cite>side_effect</cite> will be called with the same args as the mock. This gives us an |
michael@0 | 369 | opportunity to copy the arguments and store them for later assertions. In this |
michael@0 | 370 | example I’m using <em>another</em> mock to store the arguments so that I can use the |
michael@0 | 371 | mock methods for doing the assertion. Again a helper function sets this up for |
michael@0 | 372 | me.</p> |
michael@0 | 373 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">copy</span> <span class="kn">import</span> <span class="n">deepcopy</span> |
michael@0 | 374 | <span class="gp">>>> </span><span class="kn">from</span> <span class="nn">mock</span> <span class="kn">import</span> <span class="n">Mock</span><span class="p">,</span> <span class="n">patch</span><span class="p">,</span> <span class="n">DEFAULT</span> |
michael@0 | 375 | <span class="gp">>>> </span><span class="k">def</span> <span class="nf">copy_call_args</span><span class="p">(</span><span class="n">mock</span><span class="p">):</span> |
michael@0 | 376 | <span class="gp">... </span> <span class="n">new_mock</span> <span class="o">=</span> <span class="n">Mock</span><span class="p">()</span> |
michael@0 | 377 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">side_effect</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> |
michael@0 | 378 | <span class="gp">... </span> <span class="n">args</span> <span class="o">=</span> <span class="n">deepcopy</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> |
michael@0 | 379 | <span class="gp">... </span> <span class="n">kwargs</span> <span class="o">=</span> <span class="n">deepcopy</span><span class="p">(</span><span class="n">kwargs</span><span class="p">)</span> |
michael@0 | 380 | <span class="gp">... </span> <span class="n">new_mock</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> |
michael@0 | 381 | <span class="gp">... </span> <span class="k">return</span> <span class="n">DEFAULT</span> |
michael@0 | 382 | <span class="gp">... </span> <span class="n">mock</span><span class="o">.</span><span class="n">side_effect</span> <span class="o">=</span> <span class="n">side_effect</span> |
michael@0 | 383 | <span class="gp">... </span> <span class="k">return</span> <span class="n">new_mock</span> |
michael@0 | 384 | <span class="gp">...</span> |
michael@0 | 385 | <span class="gp">>>> </span><span class="k">with</span> <span class="n">patch</span><span class="p">(</span><span class="s">'mymodule.frob'</span><span class="p">)</span> <span class="k">as</span> <span class="n">mock_frob</span><span class="p">:</span> |
michael@0 | 386 | <span class="gp">... </span> <span class="n">new_mock</span> <span class="o">=</span> <span class="n">copy_call_args</span><span class="p">(</span><span class="n">mock_frob</span><span class="p">)</span> |
michael@0 | 387 | <span class="gp">... </span> <span class="n">val</span> <span class="o">=</span> <span class="nb">set</span><span class="p">([</span><span class="mi">6</span><span class="p">])</span> |
michael@0 | 388 | <span class="gp">... </span> <span class="n">mymodule</span><span class="o">.</span><span class="n">grob</span><span class="p">(</span><span class="n">val</span><span class="p">)</span> |
michael@0 | 389 | <span class="gp">...</span> |
michael@0 | 390 | <span class="gp">>>> </span><span class="n">new_mock</span><span class="o">.</span><span class="n">assert_called_with</span><span class="p">(</span><span class="nb">set</span><span class="p">([</span><span class="mi">6</span><span class="p">]))</span> |
michael@0 | 391 | <span class="gp">>>> </span><span class="n">new_mock</span><span class="o">.</span><span class="n">call_args</span> |
michael@0 | 392 | <span class="go">call(set([6]))</span> |
michael@0 | 393 | </pre></div> |
michael@0 | 394 | </div> |
michael@0 | 395 | <p><cite>copy_call_args</cite> is called with the mock that will be called. It returns a new |
michael@0 | 396 | mock that we do the assertion on. The <cite>side_effect</cite> function makes a copy of |
michael@0 | 397 | the args and calls our <cite>new_mock</cite> with the copy.</p> |
michael@0 | 398 | <div class="admonition note"> |
michael@0 | 399 | <p class="first admonition-title">Note</p> |
michael@0 | 400 | <p>If your mock is only going to be used once there is an easier way of |
michael@0 | 401 | checking arguments at the point they are called. You can simply do the |
michael@0 | 402 | checking inside a <cite>side_effect</cite> function.</p> |
michael@0 | 403 | <div class="last highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="k">def</span> <span class="nf">side_effect</span><span class="p">(</span><span class="n">arg</span><span class="p">):</span> |
michael@0 | 404 | <span class="gp">... </span> <span class="k">assert</span> <span class="n">arg</span> <span class="o">==</span> <span class="nb">set</span><span class="p">([</span><span class="mi">6</span><span class="p">])</span> |
michael@0 | 405 | <span class="gp">...</span> |
michael@0 | 406 | <span class="gp">>>> </span><span class="n">mock</span> <span class="o">=</span> <span class="n">Mock</span><span class="p">(</span><span class="n">side_effect</span><span class="o">=</span><span class="n">side_effect</span><span class="p">)</span> |
michael@0 | 407 | <span class="gp">>>> </span><span class="n">mock</span><span class="p">(</span><span class="nb">set</span><span class="p">([</span><span class="mi">6</span><span class="p">]))</span> |
michael@0 | 408 | <span class="gp">>>> </span><span class="n">mock</span><span class="p">(</span><span class="nb">set</span><span class="p">())</span> |
michael@0 | 409 | <span class="gt">Traceback (most recent call last):</span> |
michael@0 | 410 | <span class="o">...</span> |
michael@0 | 411 | <span class="gr">AssertionError</span> |
michael@0 | 412 | </pre></div> |
michael@0 | 413 | </div> |
michael@0 | 414 | </div> |
michael@0 | 415 | <p>An alternative approach is to create a subclass of <cite>Mock</cite> or <cite>MagicMock</cite> that |
michael@0 | 416 | copies (using <a class="reference external" href="http://docs.python.org/library/copy.html#copy.deepcopy">copy.deepcopy</a>) the arguments. |
michael@0 | 417 | Here’s an example implementation:</p> |
michael@0 | 418 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">copy</span> <span class="kn">import</span> <span class="n">deepcopy</span> |
michael@0 | 419 | <span class="gp">>>> </span><span class="k">class</span> <span class="nc">CopyingMock</span><span class="p">(</span><span class="n">MagicMock</span><span class="p">):</span> |
michael@0 | 420 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> |
michael@0 | 421 | <span class="gp">... </span> <span class="n">args</span> <span class="o">=</span> <span class="n">deepcopy</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> |
michael@0 | 422 | <span class="gp">... </span> <span class="n">kwargs</span> <span class="o">=</span> <span class="n">deepcopy</span><span class="p">(</span><span class="n">kwargs</span><span class="p">)</span> |
michael@0 | 423 | <span class="gp">... </span> <span class="k">return</span> <span class="nb">super</span><span class="p">(</span><span class="n">CopyingMock</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__call__</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> |
michael@0 | 424 | <span class="gp">...</span> |
michael@0 | 425 | <span class="gp">>>> </span><span class="n">c</span> <span class="o">=</span> <span class="n">CopyingMock</span><span class="p">(</span><span class="n">return_value</span><span class="o">=</span><span class="bp">None</span><span class="p">)</span> |
michael@0 | 426 | <span class="gp">>>> </span><span class="n">arg</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span> |
michael@0 | 427 | <span class="gp">>>> </span><span class="n">c</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span> |
michael@0 | 428 | <span class="gp">>>> </span><span class="n">arg</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> |
michael@0 | 429 | <span class="gp">>>> </span><span class="n">c</span><span class="o">.</span><span class="n">assert_called_with</span><span class="p">(</span><span class="nb">set</span><span class="p">())</span> |
michael@0 | 430 | <span class="gp">>>> </span><span class="n">c</span><span class="o">.</span><span class="n">assert_called_with</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span> |
michael@0 | 431 | <span class="gt">Traceback (most recent call last):</span> |
michael@0 | 432 | <span class="o">...</span> |
michael@0 | 433 | <span class="gr">AssertionError: Expected call</span>: <span class="n">mock(set([1]))</span> |
michael@0 | 434 | <span class="go">Actual call: mock(set([]))</span> |
michael@0 | 435 | <span class="gp">>>> </span><span class="n">c</span><span class="o">.</span><span class="n">foo</span> |
michael@0 | 436 | <span class="go"><CopyingMock name='mock.foo' id='...'></span> |
michael@0 | 437 | </pre></div> |
michael@0 | 438 | </div> |
michael@0 | 439 | <p>When you subclass <cite>Mock</cite> or <cite>MagicMock</cite> all dynamically created attributes, |
michael@0 | 440 | and the <cite>return_value</cite> will use your subclass automatically. That means all |
michael@0 | 441 | children of a <cite>CopyingMock</cite> will also have the type <cite>CopyingMock</cite>.</p> |
michael@0 | 442 | </div> |
michael@0 | 443 | <div class="section" id="raising-exceptions-on-attribute-access"> |
michael@0 | 444 | <h2>Raising exceptions on attribute access<a class="headerlink" href="#raising-exceptions-on-attribute-access" title="Permalink to this headline">¶</a></h2> |
michael@0 | 445 | <p>You can use <a class="reference internal" href="mock.html#mock.PropertyMock" title="mock.PropertyMock"><tt class="xref py py-class docutils literal"><span class="pre">PropertyMock</span></tt></a> to mimic the behaviour of properties. This |
michael@0 | 446 | includes raising exceptions when an attribute is accessed.</p> |
michael@0 | 447 | <p>Here’s an example raising a <cite>ValueError</cite> when the ‘foo’ attribute is accessed:</p> |
michael@0 | 448 | <div class="highlight-python"><pre>>>> m = MagicMock() |
michael@0 | 449 | >>> p = PropertyMock(side_effect=ValueError) |
michael@0 | 450 | >>> type(m).foo = p |
michael@0 | 451 | >>> m.foo |
michael@0 | 452 | Traceback (most recent call last): |
michael@0 | 453 | .... |
michael@0 | 454 | ValueError</pre> |
michael@0 | 455 | </div> |
michael@0 | 456 | <p>Because every mock object has its own type, a new subclass of whichever mock |
michael@0 | 457 | class you’re using, all mock objects are isolated from each other. You can |
michael@0 | 458 | safely attach properties (or other descriptors or whatever you want in fact) |
michael@0 | 459 | to <cite>type(mock)</cite> without affecting other mock objects.</p> |
michael@0 | 460 | </div> |
michael@0 | 461 | <div class="section" id="multiple-calls-with-different-effects"> |
michael@0 | 462 | <h2>Multiple calls with different effects<a class="headerlink" href="#multiple-calls-with-different-effects" title="Permalink to this headline">¶</a></h2> |
michael@0 | 463 | <div class="admonition note"> |
michael@0 | 464 | <p class="first admonition-title">Note</p> |
michael@0 | 465 | <p class="last">In mock 1.0 the handling of iterable <cite>side_effect</cite> was changed. Any |
michael@0 | 466 | exceptions in the iterable will be raised instead of returned.</p> |
michael@0 | 467 | </div> |
michael@0 | 468 | <p>Handling code that needs to behave differently on subsequent calls during the |
michael@0 | 469 | test can be tricky. For example you may have a function that needs to raise |
michael@0 | 470 | an exception the first time it is called but returns a response on the second |
michael@0 | 471 | call (testing retry behaviour).</p> |
michael@0 | 472 | <p>One approach is to use a <tt class="xref py py-attr docutils literal"><span class="pre">side_effect</span></tt> function that replaces itself. The |
michael@0 | 473 | first time it is called the <cite>side_effect</cite> sets a new <cite>side_effect</cite> that will |
michael@0 | 474 | be used for the second call. It then raises an exception:</p> |
michael@0 | 475 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="k">def</span> <span class="nf">side_effect</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">):</span> |
michael@0 | 476 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">second_call</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">):</span> |
michael@0 | 477 | <span class="gp">... </span> <span class="k">return</span> <span class="s">'response'</span> |
michael@0 | 478 | <span class="gp">... </span> <span class="n">mock</span><span class="o">.</span><span class="n">side_effect</span> <span class="o">=</span> <span class="n">second_call</span> |
michael@0 | 479 | <span class="gp">... </span> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s">'boom'</span><span class="p">)</span> |
michael@0 | 480 | <span class="gp">...</span> |
michael@0 | 481 | <span class="gp">>>> </span><span class="n">mock</span> <span class="o">=</span> <span class="n">Mock</span><span class="p">(</span><span class="n">side_effect</span><span class="o">=</span><span class="n">side_effect</span><span class="p">)</span> |
michael@0 | 482 | <span class="gp">>>> </span><span class="n">mock</span><span class="p">(</span><span class="s">'first'</span><span class="p">)</span> |
michael@0 | 483 | <span class="gt">Traceback (most recent call last):</span> |
michael@0 | 484 | <span class="o">...</span> |
michael@0 | 485 | <span class="gr">Exception</span>: <span class="n">boom</span> |
michael@0 | 486 | <span class="gp">>>> </span><span class="n">mock</span><span class="p">(</span><span class="s">'second'</span><span class="p">)</span> |
michael@0 | 487 | <span class="go">'response'</span> |
michael@0 | 488 | <span class="gp">>>> </span><span class="n">mock</span><span class="o">.</span><span class="n">assert_called_with</span><span class="p">(</span><span class="s">'second'</span><span class="p">)</span> |
michael@0 | 489 | </pre></div> |
michael@0 | 490 | </div> |
michael@0 | 491 | <p>Another perfectly valid way would be to pop return values from a list. If the |
michael@0 | 492 | return value is an exception, raise it instead of returning it:</p> |
michael@0 | 493 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">returns</span> <span class="o">=</span> <span class="p">[</span><span class="ne">Exception</span><span class="p">(</span><span class="s">'boom'</span><span class="p">),</span> <span class="s">'response'</span><span class="p">]</span> |
michael@0 | 494 | <span class="gp">>>> </span><span class="k">def</span> <span class="nf">side_effect</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">):</span> |
michael@0 | 495 | <span class="gp">... </span> <span class="n">result</span> <span class="o">=</span> <span class="n">returns</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> |
michael@0 | 496 | <span class="gp">... </span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="ne">Exception</span><span class="p">):</span> |
michael@0 | 497 | <span class="gp">... </span> <span class="k">raise</span> <span class="n">result</span> |
michael@0 | 498 | <span class="gp">... </span> <span class="k">return</span> <span class="n">result</span> |
michael@0 | 499 | <span class="gp">...</span> |
michael@0 | 500 | <span class="gp">>>> </span><span class="n">mock</span> <span class="o">=</span> <span class="n">Mock</span><span class="p">(</span><span class="n">side_effect</span><span class="o">=</span><span class="n">side_effect</span><span class="p">)</span> |
michael@0 | 501 | <span class="gp">>>> </span><span class="n">mock</span><span class="p">(</span><span class="s">'first'</span><span class="p">)</span> |
michael@0 | 502 | <span class="gt">Traceback (most recent call last):</span> |
michael@0 | 503 | <span class="o">...</span> |
michael@0 | 504 | <span class="gr">Exception</span>: <span class="n">boom</span> |
michael@0 | 505 | <span class="gp">>>> </span><span class="n">mock</span><span class="p">(</span><span class="s">'second'</span><span class="p">)</span> |
michael@0 | 506 | <span class="go">'response'</span> |
michael@0 | 507 | <span class="gp">>>> </span><span class="n">mock</span><span class="o">.</span><span class="n">assert_called_with</span><span class="p">(</span><span class="s">'second'</span><span class="p">)</span> |
michael@0 | 508 | </pre></div> |
michael@0 | 509 | </div> |
michael@0 | 510 | <p>Which approach you prefer is a matter of taste. The first approach is actually |
michael@0 | 511 | a line shorter but maybe the second approach is more readable.</p> |
michael@0 | 512 | </div> |
michael@0 | 513 | <div class="section" id="nesting-patches"> |
michael@0 | 514 | <h2>Nesting Patches<a class="headerlink" href="#nesting-patches" title="Permalink to this headline">¶</a></h2> |
michael@0 | 515 | <p>Using patch as a context manager is nice, but if you do multiple patches you |
michael@0 | 516 | can end up with nested with statements indenting further and further to the |
michael@0 | 517 | right:</p> |
michael@0 | 518 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="k">class</span> <span class="nc">MyTest</span><span class="p">(</span><span class="n">TestCase</span><span class="p">):</span> |
michael@0 | 519 | <span class="gp">...</span> |
michael@0 | 520 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">test_foo</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
michael@0 | 521 | <span class="gp">... </span> <span class="k">with</span> <span class="n">patch</span><span class="p">(</span><span class="s">'mymodule.Foo'</span><span class="p">)</span> <span class="k">as</span> <span class="n">mock_foo</span><span class="p">:</span> |
michael@0 | 522 | <span class="gp">... </span> <span class="k">with</span> <span class="n">patch</span><span class="p">(</span><span class="s">'mymodule.Bar'</span><span class="p">)</span> <span class="k">as</span> <span class="n">mock_bar</span><span class="p">:</span> |
michael@0 | 523 | <span class="gp">... </span> <span class="k">with</span> <span class="n">patch</span><span class="p">(</span><span class="s">'mymodule.Spam'</span><span class="p">)</span> <span class="k">as</span> <span class="n">mock_spam</span><span class="p">:</span> |
michael@0 | 524 | <span class="gp">... </span> <span class="k">assert</span> <span class="n">mymodule</span><span class="o">.</span><span class="n">Foo</span> <span class="ow">is</span> <span class="n">mock_foo</span> |
michael@0 | 525 | <span class="gp">... </span> <span class="k">assert</span> <span class="n">mymodule</span><span class="o">.</span><span class="n">Bar</span> <span class="ow">is</span> <span class="n">mock_bar</span> |
michael@0 | 526 | <span class="gp">... </span> <span class="k">assert</span> <span class="n">mymodule</span><span class="o">.</span><span class="n">Spam</span> <span class="ow">is</span> <span class="n">mock_spam</span> |
michael@0 | 527 | <span class="gp">...</span> |
michael@0 | 528 | <span class="gp">>>> </span><span class="n">original</span> <span class="o">=</span> <span class="n">mymodule</span><span class="o">.</span><span class="n">Foo</span> |
michael@0 | 529 | <span class="gp">>>> </span><span class="n">MyTest</span><span class="p">(</span><span class="s">'test_foo'</span><span class="p">)</span><span class="o">.</span><span class="n">test_foo</span><span class="p">()</span> |
michael@0 | 530 | <span class="gp">>>> </span><span class="k">assert</span> <span class="n">mymodule</span><span class="o">.</span><span class="n">Foo</span> <span class="ow">is</span> <span class="n">original</span> |
michael@0 | 531 | </pre></div> |
michael@0 | 532 | </div> |
michael@0 | 533 | <p>With <a class="reference external" href="http://pypi.python.org/pypi/unittest2">unittest2</a> <cite>cleanup</cite> functions and the <a class="reference internal" href="patch.html#start-and-stop"><em>patch methods: start and stop</em></a> we can |
michael@0 | 534 | achieve the same effect without the nested indentation. A simple helper |
michael@0 | 535 | method, <cite>create_patch</cite>, puts the patch in place and returns the created mock |
michael@0 | 536 | for us:</p> |
michael@0 | 537 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="k">class</span> <span class="nc">MyTest</span><span class="p">(</span><span class="n">TestCase</span><span class="p">):</span> |
michael@0 | 538 | <span class="gp">...</span> |
michael@0 | 539 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">create_patch</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span> |
michael@0 | 540 | <span class="gp">... </span> <span class="n">patcher</span> <span class="o">=</span> <span class="n">patch</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> |
michael@0 | 541 | <span class="gp">... </span> <span class="n">thing</span> <span class="o">=</span> <span class="n">patcher</span><span class="o">.</span><span class="n">start</span><span class="p">()</span> |
michael@0 | 542 | <span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">addCleanup</span><span class="p">(</span><span class="n">patcher</span><span class="o">.</span><span class="n">stop</span><span class="p">)</span> |
michael@0 | 543 | <span class="gp">... </span> <span class="k">return</span> <span class="n">thing</span> |
michael@0 | 544 | <span class="gp">...</span> |
michael@0 | 545 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">test_foo</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
michael@0 | 546 | <span class="gp">... </span> <span class="n">mock_foo</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">create_patch</span><span class="p">(</span><span class="s">'mymodule.Foo'</span><span class="p">)</span> |
michael@0 | 547 | <span class="gp">... </span> <span class="n">mock_bar</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">create_patch</span><span class="p">(</span><span class="s">'mymodule.Bar'</span><span class="p">)</span> |
michael@0 | 548 | <span class="gp">... </span> <span class="n">mock_spam</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">create_patch</span><span class="p">(</span><span class="s">'mymodule.Spam'</span><span class="p">)</span> |
michael@0 | 549 | <span class="gp">...</span> |
michael@0 | 550 | <span class="gp">... </span> <span class="k">assert</span> <span class="n">mymodule</span><span class="o">.</span><span class="n">Foo</span> <span class="ow">is</span> <span class="n">mock_foo</span> |
michael@0 | 551 | <span class="gp">... </span> <span class="k">assert</span> <span class="n">mymodule</span><span class="o">.</span><span class="n">Bar</span> <span class="ow">is</span> <span class="n">mock_bar</span> |
michael@0 | 552 | <span class="gp">... </span> <span class="k">assert</span> <span class="n">mymodule</span><span class="o">.</span><span class="n">Spam</span> <span class="ow">is</span> <span class="n">mock_spam</span> |
michael@0 | 553 | <span class="gp">...</span> |
michael@0 | 554 | <span class="gp">>>> </span><span class="n">original</span> <span class="o">=</span> <span class="n">mymodule</span><span class="o">.</span><span class="n">Foo</span> |
michael@0 | 555 | <span class="gp">>>> </span><span class="n">MyTest</span><span class="p">(</span><span class="s">'test_foo'</span><span class="p">)</span><span class="o">.</span><span class="n">run</span><span class="p">()</span> |
michael@0 | 556 | <span class="gp">>>> </span><span class="k">assert</span> <span class="n">mymodule</span><span class="o">.</span><span class="n">Foo</span> <span class="ow">is</span> <span class="n">original</span> |
michael@0 | 557 | </pre></div> |
michael@0 | 558 | </div> |
michael@0 | 559 | </div> |
michael@0 | 560 | <div class="section" id="mocking-a-dictionary-with-magicmock"> |
michael@0 | 561 | <h2>Mocking a dictionary with MagicMock<a class="headerlink" href="#mocking-a-dictionary-with-magicmock" title="Permalink to this headline">¶</a></h2> |
michael@0 | 562 | <p>You may want to mock a dictionary, or other container object, recording all |
michael@0 | 563 | access to it whilst having it still behave like a dictionary.</p> |
michael@0 | 564 | <p>We can do this with <a class="reference internal" href="magicmock.html#mock.MagicMock" title="mock.MagicMock"><tt class="xref py py-class docutils literal"><span class="pre">MagicMock</span></tt></a>, which will behave like a dictionary, |
michael@0 | 565 | and using <a class="reference internal" href="mock.html#mock.Mock.side_effect" title="mock.Mock.side_effect"><tt class="xref py py-data docutils literal"><span class="pre">side_effect</span></tt></a> to delegate dictionary access to a real |
michael@0 | 566 | underlying dictionary that is under our control.</p> |
michael@0 | 567 | <p>When the <cite>__getitem__</cite> and <cite>__setitem__</cite> methods of our <cite>MagicMock</cite> are called |
michael@0 | 568 | (normal dictionary access) then <cite>side_effect</cite> is called with the key (and in |
michael@0 | 569 | the case of <cite>__setitem__</cite> the value too). We can also control what is returned.</p> |
michael@0 | 570 | <p>After the <cite>MagicMock</cite> has been used we can use attributes like |
michael@0 | 571 | <a class="reference internal" href="mock.html#mock.Mock.call_args_list" title="mock.Mock.call_args_list"><tt class="xref py py-data docutils literal"><span class="pre">call_args_list</span></tt></a> to assert about how the dictionary was used:</p> |
michael@0 | 572 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">my_dict</span> <span class="o">=</span> <span class="p">{</span><span class="s">'a'</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="s">'b'</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span> <span class="s">'c'</span><span class="p">:</span> <span class="mi">3</span><span class="p">}</span> |
michael@0 | 573 | <span class="gp">>>> </span><span class="k">def</span> <span class="nf">getitem</span><span class="p">(</span><span class="n">name</span><span class="p">):</span> |
michael@0 | 574 | <span class="gp">... </span> <span class="k">return</span> <span class="n">my_dict</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> |
michael@0 | 575 | <span class="gp">...</span> |
michael@0 | 576 | <span class="gp">>>> </span><span class="k">def</span> <span class="nf">setitem</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">val</span><span class="p">):</span> |
michael@0 | 577 | <span class="gp">... </span> <span class="n">my_dict</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">val</span> |
michael@0 | 578 | <span class="gp">...</span> |
michael@0 | 579 | <span class="gp">>>> </span><span class="n">mock</span> <span class="o">=</span> <span class="n">MagicMock</span><span class="p">()</span> |
michael@0 | 580 | <span class="gp">>>> </span><span class="n">mock</span><span class="o">.</span><span class="n">__getitem__</span><span class="o">.</span><span class="n">side_effect</span> <span class="o">=</span> <span class="n">getitem</span> |
michael@0 | 581 | <span class="gp">>>> </span><span class="n">mock</span><span class="o">.</span><span class="n">__setitem__</span><span class="o">.</span><span class="n">side_effect</span> <span class="o">=</span> <span class="n">setitem</span> |
michael@0 | 582 | </pre></div> |
michael@0 | 583 | </div> |
michael@0 | 584 | <div class="admonition note"> |
michael@0 | 585 | <p class="first admonition-title">Note</p> |
michael@0 | 586 | <p>An alternative to using <cite>MagicMock</cite> is to use <cite>Mock</cite> and <em>only</em> provide |
michael@0 | 587 | the magic methods you specifically want:</p> |
michael@0 | 588 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">mock</span> <span class="o">=</span> <span class="n">Mock</span><span class="p">()</span> |
michael@0 | 589 | <span class="gp">>>> </span><span class="n">mock</span><span class="o">.</span><span class="n">__setitem__</span> <span class="o">=</span> <span class="n">Mock</span><span class="p">(</span><span class="n">side_effect</span><span class="o">=</span><span class="n">getitem</span><span class="p">)</span> |
michael@0 | 590 | <span class="gp">>>> </span><span class="n">mock</span><span class="o">.</span><span class="n">__getitem__</span> <span class="o">=</span> <span class="n">Mock</span><span class="p">(</span><span class="n">side_effect</span><span class="o">=</span><span class="n">setitem</span><span class="p">)</span> |
michael@0 | 591 | </pre></div> |
michael@0 | 592 | </div> |
michael@0 | 593 | <p>A <em>third</em> option is to use <cite>MagicMock</cite> but passing in <cite>dict</cite> as the <cite>spec</cite> |
michael@0 | 594 | (or <cite>spec_set</cite>) argument so that the <cite>MagicMock</cite> created only has |
michael@0 | 595 | dictionary magic methods available:</p> |
michael@0 | 596 | <div class="last highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">mock</span> <span class="o">=</span> <span class="n">MagicMock</span><span class="p">(</span><span class="n">spec_set</span><span class="o">=</span><span class="nb">dict</span><span class="p">)</span> |
michael@0 | 597 | <span class="gp">>>> </span><span class="n">mock</span><span class="o">.</span><span class="n">__getitem__</span><span class="o">.</span><span class="n">side_effect</span> <span class="o">=</span> <span class="n">getitem</span> |
michael@0 | 598 | <span class="gp">>>> </span><span class="n">mock</span><span class="o">.</span><span class="n">__setitem__</span><span class="o">.</span><span class="n">side_effect</span> <span class="o">=</span> <span class="n">setitem</span> |
michael@0 | 599 | </pre></div> |
michael@0 | 600 | </div> |
michael@0 | 601 | </div> |
michael@0 | 602 | <p>With these side effect functions in place, the <cite>mock</cite> will behave like a normal |
michael@0 | 603 | dictionary but recording the access. It even raises a <cite>KeyError</cite> if you try |
michael@0 | 604 | to access a key that doesn’t exist.</p> |
michael@0 | 605 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">mock</span><span class="p">[</span><span class="s">'a'</span><span class="p">]</span> |
michael@0 | 606 | <span class="go">1</span> |
michael@0 | 607 | <span class="gp">>>> </span><span class="n">mock</span><span class="p">[</span><span class="s">'c'</span><span class="p">]</span> |
michael@0 | 608 | <span class="go">3</span> |
michael@0 | 609 | <span class="gp">>>> </span><span class="n">mock</span><span class="p">[</span><span class="s">'d'</span><span class="p">]</span> |
michael@0 | 610 | <span class="gt">Traceback (most recent call last):</span> |
michael@0 | 611 | <span class="o">...</span> |
michael@0 | 612 | <span class="gr">KeyError</span>: <span class="n">'d'</span> |
michael@0 | 613 | <span class="gp">>>> </span><span class="n">mock</span><span class="p">[</span><span class="s">'b'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'fish'</span> |
michael@0 | 614 | <span class="gp">>>> </span><span class="n">mock</span><span class="p">[</span><span class="s">'d'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'eggs'</span> |
michael@0 | 615 | <span class="gp">>>> </span><span class="n">mock</span><span class="p">[</span><span class="s">'b'</span><span class="p">]</span> |
michael@0 | 616 | <span class="go">'fish'</span> |
michael@0 | 617 | <span class="gp">>>> </span><span class="n">mock</span><span class="p">[</span><span class="s">'d'</span><span class="p">]</span> |
michael@0 | 618 | <span class="go">'eggs'</span> |
michael@0 | 619 | </pre></div> |
michael@0 | 620 | </div> |
michael@0 | 621 | <p>After it has been used you can make assertions about the access using the normal |
michael@0 | 622 | mock methods and attributes:</p> |
michael@0 | 623 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">mock</span><span class="o">.</span><span class="n">__getitem__</span><span class="o">.</span><span class="n">call_args_list</span> |
michael@0 | 624 | <span class="go">[call('a'), call('c'), call('d'), call('b'), call('d')]</span> |
michael@0 | 625 | <span class="gp">>>> </span><span class="n">mock</span><span class="o">.</span><span class="n">__setitem__</span><span class="o">.</span><span class="n">call_args_list</span> |
michael@0 | 626 | <span class="go">[call('b', 'fish'), call('d', 'eggs')]</span> |
michael@0 | 627 | <span class="gp">>>> </span><span class="n">my_dict</span> |
michael@0 | 628 | <span class="go">{'a': 1, 'c': 3, 'b': 'fish', 'd': 'eggs'}</span> |
michael@0 | 629 | </pre></div> |
michael@0 | 630 | </div> |
michael@0 | 631 | </div> |
michael@0 | 632 | <div class="section" id="mock-subclasses-and-their-attributes"> |
michael@0 | 633 | <h2>Mock subclasses and their attributes<a class="headerlink" href="#mock-subclasses-and-their-attributes" title="Permalink to this headline">¶</a></h2> |
michael@0 | 634 | <p>There are various reasons why you might want to subclass <cite>Mock</cite>. One reason |
michael@0 | 635 | might be to add helper methods. Here’s a silly example:</p> |
michael@0 | 636 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="k">class</span> <span class="nc">MyMock</span><span class="p">(</span><span class="n">MagicMock</span><span class="p">):</span> |
michael@0 | 637 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">has_been_called</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
michael@0 | 638 | <span class="gp">... </span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">called</span> |
michael@0 | 639 | <span class="gp">...</span> |
michael@0 | 640 | <span class="gp">>>> </span><span class="n">mymock</span> <span class="o">=</span> <span class="n">MyMock</span><span class="p">(</span><span class="n">return_value</span><span class="o">=</span><span class="bp">None</span><span class="p">)</span> |
michael@0 | 641 | <span class="gp">>>> </span><span class="n">mymock</span> |
michael@0 | 642 | <span class="go"><MyMock id='...'></span> |
michael@0 | 643 | <span class="gp">>>> </span><span class="n">mymock</span><span class="o">.</span><span class="n">has_been_called</span><span class="p">()</span> |
michael@0 | 644 | <span class="go">False</span> |
michael@0 | 645 | <span class="gp">>>> </span><span class="n">mymock</span><span class="p">()</span> |
michael@0 | 646 | <span class="gp">>>> </span><span class="n">mymock</span><span class="o">.</span><span class="n">has_been_called</span><span class="p">()</span> |
michael@0 | 647 | <span class="go">True</span> |
michael@0 | 648 | </pre></div> |
michael@0 | 649 | </div> |
michael@0 | 650 | <p>The standard behaviour for <cite>Mock</cite> instances is that attributes and the return |
michael@0 | 651 | value mocks are of the same type as the mock they are accessed on. This ensures |
michael@0 | 652 | that <cite>Mock</cite> attributes are <cite>Mocks</cite> and <cite>MagicMock</cite> attributes are <cite>MagicMocks</cite> |
michael@0 | 653 | <a class="footnote-reference" href="#id5" id="id4">[2]</a>. So if you’re subclassing to add helper methods then they’ll also be |
michael@0 | 654 | available on the attributes and return value mock of instances of your |
michael@0 | 655 | subclass.</p> |
michael@0 | 656 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">mymock</span><span class="o">.</span><span class="n">foo</span> |
michael@0 | 657 | <span class="go"><MyMock name='mock.foo' id='...'></span> |
michael@0 | 658 | <span class="gp">>>> </span><span class="n">mymock</span><span class="o">.</span><span class="n">foo</span><span class="o">.</span><span class="n">has_been_called</span><span class="p">()</span> |
michael@0 | 659 | <span class="go">False</span> |
michael@0 | 660 | <span class="gp">>>> </span><span class="n">mymock</span><span class="o">.</span><span class="n">foo</span><span class="p">()</span> |
michael@0 | 661 | <span class="go"><MyMock name='mock.foo()' id='...'></span> |
michael@0 | 662 | <span class="gp">>>> </span><span class="n">mymock</span><span class="o">.</span><span class="n">foo</span><span class="o">.</span><span class="n">has_been_called</span><span class="p">()</span> |
michael@0 | 663 | <span class="go">True</span> |
michael@0 | 664 | </pre></div> |
michael@0 | 665 | </div> |
michael@0 | 666 | <p>Sometimes this is inconvenient. For example, <a class="reference external" href="https://code.google.com/p/mock/issues/detail?id=105">one user</a> is subclassing mock to |
michael@0 | 667 | created a <a class="reference external" href="http://twistedmatrix.com/documents/11.0.0/api/twisted.python.components.html">Twisted adaptor</a>. |
michael@0 | 668 | Having this applied to attributes too actually causes errors.</p> |
michael@0 | 669 | <p><cite>Mock</cite> (in all its flavours) uses a method called <cite>_get_child_mock</cite> to create |
michael@0 | 670 | these “sub-mocks” for attributes and return values. You can prevent your |
michael@0 | 671 | subclass being used for attributes by overriding this method. The signature is |
michael@0 | 672 | that it takes arbitrary keyword arguments (<cite>**kwargs</cite>) which are then passed |
michael@0 | 673 | onto the mock constructor:</p> |
michael@0 | 674 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="k">class</span> <span class="nc">Subclass</span><span class="p">(</span><span class="n">MagicMock</span><span class="p">):</span> |
michael@0 | 675 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">_get_child_mock</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> |
michael@0 | 676 | <span class="gp">... </span> <span class="k">return</span> <span class="n">MagicMock</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> |
michael@0 | 677 | <span class="gp">...</span> |
michael@0 | 678 | <span class="gp">>>> </span><span class="n">mymock</span> <span class="o">=</span> <span class="n">Subclass</span><span class="p">()</span> |
michael@0 | 679 | <span class="gp">>>> </span><span class="n">mymock</span><span class="o">.</span><span class="n">foo</span> |
michael@0 | 680 | <span class="go"><MagicMock name='mock.foo' id='...'></span> |
michael@0 | 681 | <span class="gp">>>> </span><span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">mymock</span><span class="p">,</span> <span class="n">Subclass</span><span class="p">)</span> |
michael@0 | 682 | <span class="gp">>>> </span><span class="k">assert</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">mymock</span><span class="o">.</span><span class="n">foo</span><span class="p">,</span> <span class="n">Subclass</span><span class="p">)</span> |
michael@0 | 683 | <span class="gp">>>> </span><span class="k">assert</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">mymock</span><span class="p">(),</span> <span class="n">Subclass</span><span class="p">)</span> |
michael@0 | 684 | </pre></div> |
michael@0 | 685 | </div> |
michael@0 | 686 | <table class="docutils footnote" frame="void" id="id5" rules="none"> |
michael@0 | 687 | <colgroup><col class="label" /><col /></colgroup> |
michael@0 | 688 | <tbody valign="top"> |
michael@0 | 689 | <tr><td class="label"><a class="fn-backref" href="#id4">[2]</a></td><td>An exception to this rule are the non-callable mocks. Attributes use the |
michael@0 | 690 | callable variant because otherwise non-callable mocks couldn’t have callable |
michael@0 | 691 | methods.</td></tr> |
michael@0 | 692 | </tbody> |
michael@0 | 693 | </table> |
michael@0 | 694 | </div> |
michael@0 | 695 | <div class="section" id="mocking-imports-with-patch-dict"> |
michael@0 | 696 | <h2>Mocking imports with patch.dict<a class="headerlink" href="#mocking-imports-with-patch-dict" title="Permalink to this headline">¶</a></h2> |
michael@0 | 697 | <p>One situation where mocking can be hard is where you have a local import inside |
michael@0 | 698 | a function. These are harder to mock because they aren’t using an object from |
michael@0 | 699 | the module namespace that we can patch out.</p> |
michael@0 | 700 | <p>Generally local imports are to be avoided. They are sometimes done to prevent |
michael@0 | 701 | circular dependencies, for which there is <em>usually</em> a much better way to solve |
michael@0 | 702 | the problem (refactor the code) or to prevent “up front costs” by delaying the |
michael@0 | 703 | import. This can also be solved in better ways than an unconditional local |
michael@0 | 704 | import (store the module as a class or module attribute and only do the import |
michael@0 | 705 | on first use).</p> |
michael@0 | 706 | <p>That aside there is a way to use <cite>mock</cite> to affect the results of an import. |
michael@0 | 707 | Importing fetches an <em>object</em> from the <cite>sys.modules</cite> dictionary. Note that it |
michael@0 | 708 | fetches an <em>object</em>, which need not be a module. Importing a module for the |
michael@0 | 709 | first time results in a module object being put in <cite>sys.modules</cite>, so usually |
michael@0 | 710 | when you import something you get a module back. This need not be the case |
michael@0 | 711 | however.</p> |
michael@0 | 712 | <p>This means you can use <a class="reference internal" href="patch.html#mock.patch.dict" title="mock.patch.dict"><tt class="xref py py-func docutils literal"><span class="pre">patch.dict()</span></tt></a> to <em>temporarily</em> put a mock in place |
michael@0 | 713 | in <cite>sys.modules</cite>. Any imports whilst this patch is active will fetch the mock. |
michael@0 | 714 | When the patch is complete (the decorated function exits, the with statement |
michael@0 | 715 | body is complete or <cite>patcher.stop()</cite> is called) then whatever was there |
michael@0 | 716 | previously will be restored safely.</p> |
michael@0 | 717 | <p>Here’s an example that mocks out the ‘fooble’ module.</p> |
michael@0 | 718 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">mock</span> <span class="o">=</span> <span class="n">Mock</span><span class="p">()</span> |
michael@0 | 719 | <span class="gp">>>> </span><span class="k">with</span> <span class="n">patch</span><span class="o">.</span><span class="n">dict</span><span class="p">(</span><span class="s">'sys.modules'</span><span class="p">,</span> <span class="p">{</span><span class="s">'fooble'</span><span class="p">:</span> <span class="n">mock</span><span class="p">}):</span> |
michael@0 | 720 | <span class="gp">... </span> <span class="kn">import</span> <span class="nn">fooble</span> |
michael@0 | 721 | <span class="gp">... </span> <span class="n">fooble</span><span class="o">.</span><span class="n">blob</span><span class="p">()</span> |
michael@0 | 722 | <span class="gp">...</span> |
michael@0 | 723 | <span class="go"><Mock name='mock.blob()' id='...'></span> |
michael@0 | 724 | <span class="gp">>>> </span><span class="k">assert</span> <span class="s">'fooble'</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">sys</span><span class="o">.</span><span class="n">modules</span> |
michael@0 | 725 | <span class="gp">>>> </span><span class="n">mock</span><span class="o">.</span><span class="n">blob</span><span class="o">.</span><span class="n">assert_called_once_with</span><span class="p">()</span> |
michael@0 | 726 | </pre></div> |
michael@0 | 727 | </div> |
michael@0 | 728 | <p>As you can see the <cite>import fooble</cite> succeeds, but on exit there is no ‘fooble’ |
michael@0 | 729 | left in <cite>sys.modules</cite>.</p> |
michael@0 | 730 | <p>This also works for the <cite>from module import name</cite> form:</p> |
michael@0 | 731 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">mock</span> <span class="o">=</span> <span class="n">Mock</span><span class="p">()</span> |
michael@0 | 732 | <span class="gp">>>> </span><span class="k">with</span> <span class="n">patch</span><span class="o">.</span><span class="n">dict</span><span class="p">(</span><span class="s">'sys.modules'</span><span class="p">,</span> <span class="p">{</span><span class="s">'fooble'</span><span class="p">:</span> <span class="n">mock</span><span class="p">}):</span> |
michael@0 | 733 | <span class="gp">... </span> <span class="kn">from</span> <span class="nn">fooble</span> <span class="kn">import</span> <span class="n">blob</span> |
michael@0 | 734 | <span class="gp">... </span> <span class="n">blob</span><span class="o">.</span><span class="n">blip</span><span class="p">()</span> |
michael@0 | 735 | <span class="gp">...</span> |
michael@0 | 736 | <span class="go"><Mock name='mock.blob.blip()' id='...'></span> |
michael@0 | 737 | <span class="gp">>>> </span><span class="n">mock</span><span class="o">.</span><span class="n">blob</span><span class="o">.</span><span class="n">blip</span><span class="o">.</span><span class="n">assert_called_once_with</span><span class="p">()</span> |
michael@0 | 738 | </pre></div> |
michael@0 | 739 | </div> |
michael@0 | 740 | <p>With slightly more work you can also mock package imports:</p> |
michael@0 | 741 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">mock</span> <span class="o">=</span> <span class="n">Mock</span><span class="p">()</span> |
michael@0 | 742 | <span class="gp">>>> </span><span class="n">modules</span> <span class="o">=</span> <span class="p">{</span><span class="s">'package'</span><span class="p">:</span> <span class="n">mock</span><span class="p">,</span> <span class="s">'package.module'</span><span class="p">:</span> <span class="n">mock</span><span class="o">.</span><span class="n">module</span><span class="p">}</span> |
michael@0 | 743 | <span class="gp">>>> </span><span class="k">with</span> <span class="n">patch</span><span class="o">.</span><span class="n">dict</span><span class="p">(</span><span class="s">'sys.modules'</span><span class="p">,</span> <span class="n">modules</span><span class="p">):</span> |
michael@0 | 744 | <span class="gp">... </span> <span class="kn">from</span> <span class="nn">package.module</span> <span class="kn">import</span> <span class="n">fooble</span> |
michael@0 | 745 | <span class="gp">... </span> <span class="n">fooble</span><span class="p">()</span> |
michael@0 | 746 | <span class="gp">...</span> |
michael@0 | 747 | <span class="go"><Mock name='mock.module.fooble()' id='...'></span> |
michael@0 | 748 | <span class="gp">>>> </span><span class="n">mock</span><span class="o">.</span><span class="n">module</span><span class="o">.</span><span class="n">fooble</span><span class="o">.</span><span class="n">assert_called_once_with</span><span class="p">()</span> |
michael@0 | 749 | </pre></div> |
michael@0 | 750 | </div> |
michael@0 | 751 | </div> |
michael@0 | 752 | <div class="section" id="tracking-order-of-calls-and-less-verbose-call-assertions"> |
michael@0 | 753 | <h2>Tracking order of calls and less verbose call assertions<a class="headerlink" href="#tracking-order-of-calls-and-less-verbose-call-assertions" title="Permalink to this headline">¶</a></h2> |
michael@0 | 754 | <p>The <a class="reference internal" href="mock.html#mock.Mock" title="mock.Mock"><tt class="xref py py-class docutils literal"><span class="pre">Mock</span></tt></a> class allows you to track the <em>order</em> of method calls on |
michael@0 | 755 | your mock objects through the <a class="reference internal" href="mock.html#mock.Mock.method_calls" title="mock.Mock.method_calls"><tt class="xref py py-attr docutils literal"><span class="pre">method_calls</span></tt></a> attribute. This |
michael@0 | 756 | doesn’t allow you to track the order of calls between separate mock objects, |
michael@0 | 757 | however we can use <a class="reference internal" href="mock.html#mock.Mock.mock_calls" title="mock.Mock.mock_calls"><tt class="xref py py-attr docutils literal"><span class="pre">mock_calls</span></tt></a> to achieve the same effect.</p> |
michael@0 | 758 | <p>Because mocks track calls to child mocks in <cite>mock_calls</cite>, and accessing an |
michael@0 | 759 | arbitrary attribute of a mock creates a child mock, we can create our separate |
michael@0 | 760 | mocks from a parent one. Calls to those child mock will then all be recorded, |
michael@0 | 761 | in order, in the <cite>mock_calls</cite> of the parent:</p> |
michael@0 | 762 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">manager</span> <span class="o">=</span> <span class="n">Mock</span><span class="p">()</span> |
michael@0 | 763 | <span class="gp">>>> </span><span class="n">mock_foo</span> <span class="o">=</span> <span class="n">manager</span><span class="o">.</span><span class="n">foo</span> |
michael@0 | 764 | <span class="gp">>>> </span><span class="n">mock_bar</span> <span class="o">=</span> <span class="n">manager</span><span class="o">.</span><span class="n">bar</span> |
michael@0 | 765 | |
michael@0 | 766 | <span class="gp">>>> </span><span class="n">mock_foo</span><span class="o">.</span><span class="n">something</span><span class="p">()</span> |
michael@0 | 767 | <span class="go"><Mock name='mock.foo.something()' id='...'></span> |
michael@0 | 768 | <span class="gp">>>> </span><span class="n">mock_bar</span><span class="o">.</span><span class="n">other</span><span class="o">.</span><span class="n">thing</span><span class="p">()</span> |
michael@0 | 769 | <span class="go"><Mock name='mock.bar.other.thing()' id='...'></span> |
michael@0 | 770 | |
michael@0 | 771 | <span class="gp">>>> </span><span class="n">manager</span><span class="o">.</span><span class="n">mock_calls</span> |
michael@0 | 772 | <span class="go">[call.foo.something(), call.bar.other.thing()]</span> |
michael@0 | 773 | </pre></div> |
michael@0 | 774 | </div> |
michael@0 | 775 | <p>We can then assert about the calls, including the order, by comparing with |
michael@0 | 776 | the <cite>mock_calls</cite> attribute on the manager mock:</p> |
michael@0 | 777 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">expected_calls</span> <span class="o">=</span> <span class="p">[</span><span class="n">call</span><span class="o">.</span><span class="n">foo</span><span class="o">.</span><span class="n">something</span><span class="p">(),</span> <span class="n">call</span><span class="o">.</span><span class="n">bar</span><span class="o">.</span><span class="n">other</span><span class="o">.</span><span class="n">thing</span><span class="p">()]</span> |
michael@0 | 778 | <span class="gp">>>> </span><span class="n">manager</span><span class="o">.</span><span class="n">mock_calls</span> <span class="o">==</span> <span class="n">expected_calls</span> |
michael@0 | 779 | <span class="go">True</span> |
michael@0 | 780 | </pre></div> |
michael@0 | 781 | </div> |
michael@0 | 782 | <p>If <cite>patch</cite> is creating, and putting in place, your mocks then you can attach |
michael@0 | 783 | them to a manager mock using the <a class="reference internal" href="mock.html#mock.Mock.attach_mock" title="mock.Mock.attach_mock"><tt class="xref py py-meth docutils literal"><span class="pre">attach_mock()</span></tt></a> method. After |
michael@0 | 784 | attaching calls will be recorded in <cite>mock_calls</cite> of the manager.</p> |
michael@0 | 785 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">manager</span> <span class="o">=</span> <span class="n">MagicMock</span><span class="p">()</span> |
michael@0 | 786 | <span class="gp">>>> </span><span class="k">with</span> <span class="n">patch</span><span class="p">(</span><span class="s">'mymodule.Class1'</span><span class="p">)</span> <span class="k">as</span> <span class="n">MockClass1</span><span class="p">:</span> |
michael@0 | 787 | <span class="gp">... </span> <span class="k">with</span> <span class="n">patch</span><span class="p">(</span><span class="s">'mymodule.Class2'</span><span class="p">)</span> <span class="k">as</span> <span class="n">MockClass2</span><span class="p">:</span> |
michael@0 | 788 | <span class="gp">... </span> <span class="n">manager</span><span class="o">.</span><span class="n">attach_mock</span><span class="p">(</span><span class="n">MockClass1</span><span class="p">,</span> <span class="s">'MockClass1'</span><span class="p">)</span> |
michael@0 | 789 | <span class="gp">... </span> <span class="n">manager</span><span class="o">.</span><span class="n">attach_mock</span><span class="p">(</span><span class="n">MockClass2</span><span class="p">,</span> <span class="s">'MockClass2'</span><span class="p">)</span> |
michael@0 | 790 | <span class="gp">... </span> <span class="n">MockClass1</span><span class="p">()</span><span class="o">.</span><span class="n">foo</span><span class="p">()</span> |
michael@0 | 791 | <span class="gp">... </span> <span class="n">MockClass2</span><span class="p">()</span><span class="o">.</span><span class="n">bar</span><span class="p">()</span> |
michael@0 | 792 | <span class="gp">...</span> |
michael@0 | 793 | <span class="go"><MagicMock name='mock.MockClass1().foo()' id='...'></span> |
michael@0 | 794 | <span class="go"><MagicMock name='mock.MockClass2().bar()' id='...'></span> |
michael@0 | 795 | <span class="gp">>>> </span><span class="n">manager</span><span class="o">.</span><span class="n">mock_calls</span> |
michael@0 | 796 | <span class="go">[call.MockClass1(),</span> |
michael@0 | 797 | <span class="go"> call.MockClass1().foo(),</span> |
michael@0 | 798 | <span class="go"> call.MockClass2(),</span> |
michael@0 | 799 | <span class="go"> call.MockClass2().bar()]</span> |
michael@0 | 800 | </pre></div> |
michael@0 | 801 | </div> |
michael@0 | 802 | <p>If many calls have been made, but you’re only interested in a particular |
michael@0 | 803 | sequence of them then an alternative is to use the |
michael@0 | 804 | <a class="reference internal" href="mock.html#mock.Mock.assert_has_calls" title="mock.Mock.assert_has_calls"><tt class="xref py py-meth docutils literal"><span class="pre">assert_has_calls()</span></tt></a> method. This takes a list of calls (constructed |
michael@0 | 805 | with the <a class="reference internal" href="helpers.html#mock.call" title="mock.call"><tt class="xref py py-data docutils literal"><span class="pre">call</span></tt></a> object). If that sequence of calls are in |
michael@0 | 806 | <a class="reference internal" href="mock.html#mock.Mock.mock_calls" title="mock.Mock.mock_calls"><tt class="xref py py-attr docutils literal"><span class="pre">mock_calls</span></tt></a> then the assert succeeds.</p> |
michael@0 | 807 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">m</span> <span class="o">=</span> <span class="n">MagicMock</span><span class="p">()</span> |
michael@0 | 808 | <span class="gp">>>> </span><span class="n">m</span><span class="p">()</span><span class="o">.</span><span class="n">foo</span><span class="p">()</span><span class="o">.</span><span class="n">bar</span><span class="p">()</span><span class="o">.</span><span class="n">baz</span><span class="p">()</span> |
michael@0 | 809 | <span class="go"><MagicMock name='mock().foo().bar().baz()' id='...'></span> |
michael@0 | 810 | <span class="gp">>>> </span><span class="n">m</span><span class="o">.</span><span class="n">one</span><span class="p">()</span><span class="o">.</span><span class="n">two</span><span class="p">()</span><span class="o">.</span><span class="n">three</span><span class="p">()</span> |
michael@0 | 811 | <span class="go"><MagicMock name='mock.one().two().three()' id='...'></span> |
michael@0 | 812 | <span class="gp">>>> </span><span class="n">calls</span> <span class="o">=</span> <span class="n">call</span><span class="o">.</span><span class="n">one</span><span class="p">()</span><span class="o">.</span><span class="n">two</span><span class="p">()</span><span class="o">.</span><span class="n">three</span><span class="p">()</span><span class="o">.</span><span class="n">call_list</span><span class="p">()</span> |
michael@0 | 813 | <span class="gp">>>> </span><span class="n">m</span><span class="o">.</span><span class="n">assert_has_calls</span><span class="p">(</span><span class="n">calls</span><span class="p">)</span> |
michael@0 | 814 | </pre></div> |
michael@0 | 815 | </div> |
michael@0 | 816 | <p>Even though the chained call <cite>m.one().two().three()</cite> aren’t the only calls that |
michael@0 | 817 | have been made to the mock, the assert still succeeds.</p> |
michael@0 | 818 | <p>Sometimes a mock may have several calls made to it, and you are only interested |
michael@0 | 819 | in asserting about <em>some</em> of those calls. You may not even care about the |
michael@0 | 820 | order. In this case you can pass <cite>any_order=True</cite> to <cite>assert_has_calls</cite>:</p> |
michael@0 | 821 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">m</span> <span class="o">=</span> <span class="n">MagicMock</span><span class="p">()</span> |
michael@0 | 822 | <span class="gp">>>> </span><span class="n">m</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="n">m</span><span class="o">.</span><span class="n">two</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="n">m</span><span class="o">.</span><span class="n">seven</span><span class="p">(</span><span class="mi">7</span><span class="p">),</span> <span class="n">m</span><span class="o">.</span><span class="n">fifty</span><span class="p">(</span><span class="s">'50'</span><span class="p">)</span> |
michael@0 | 823 | <span class="go">(...)</span> |
michael@0 | 824 | <span class="gp">>>> </span><span class="n">calls</span> <span class="o">=</span> <span class="p">[</span><span class="n">call</span><span class="o">.</span><span class="n">fifty</span><span class="p">(</span><span class="s">'50'</span><span class="p">),</span> <span class="n">call</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="n">call</span><span class="o">.</span><span class="n">seven</span><span class="p">(</span><span class="mi">7</span><span class="p">)]</span> |
michael@0 | 825 | <span class="gp">>>> </span><span class="n">m</span><span class="o">.</span><span class="n">assert_has_calls</span><span class="p">(</span><span class="n">calls</span><span class="p">,</span> <span class="n">any_order</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span> |
michael@0 | 826 | </pre></div> |
michael@0 | 827 | </div> |
michael@0 | 828 | </div> |
michael@0 | 829 | <div class="section" id="more-complex-argument-matching"> |
michael@0 | 830 | <h2>More complex argument matching<a class="headerlink" href="#more-complex-argument-matching" title="Permalink to this headline">¶</a></h2> |
michael@0 | 831 | <p>Using the same basic concept as <cite>ANY</cite> we can implement matchers to do more |
michael@0 | 832 | complex assertions on objects used as arguments to mocks.</p> |
michael@0 | 833 | <p>Suppose we expect some object to be passed to a mock that by default |
michael@0 | 834 | compares equal based on object identity (which is the Python default for user |
michael@0 | 835 | defined classes). To use <a class="reference internal" href="mock.html#mock.Mock.assert_called_with" title="mock.Mock.assert_called_with"><tt class="xref py py-meth docutils literal"><span class="pre">assert_called_with()</span></tt></a> we would need to pass |
michael@0 | 836 | in the exact same object. If we are only interested in some of the attributes |
michael@0 | 837 | of this object then we can create a matcher that will check these attributes |
michael@0 | 838 | for us.</p> |
michael@0 | 839 | <p>You can see in this example how a ‘standard’ call to <cite>assert_called_with</cite> isn’t |
michael@0 | 840 | sufficient:</p> |
michael@0 | 841 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="k">class</span> <span class="nc">Foo</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> |
michael@0 | 842 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span> |
michael@0 | 843 | <span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">a</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">b</span> <span class="o">=</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> |
michael@0 | 844 | <span class="gp">...</span> |
michael@0 | 845 | <span class="gp">>>> </span><span class="n">mock</span> <span class="o">=</span> <span class="n">Mock</span><span class="p">(</span><span class="n">return_value</span><span class="o">=</span><span class="bp">None</span><span class="p">)</span> |
michael@0 | 846 | <span class="gp">>>> </span><span class="n">mock</span><span class="p">(</span><span class="n">Foo</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span> |
michael@0 | 847 | <span class="gp">>>> </span><span class="n">mock</span><span class="o">.</span><span class="n">assert_called_with</span><span class="p">(</span><span class="n">Foo</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span> |
michael@0 | 848 | <span class="gt">Traceback (most recent call last):</span> |
michael@0 | 849 | <span class="o">...</span> |
michael@0 | 850 | <span class="gr">AssertionError: Expected</span>: <span class="n">call(<__main__.Foo object at 0x...>)</span> |
michael@0 | 851 | <span class="go">Actual call: call(<__main__.Foo object at 0x...>)</span> |
michael@0 | 852 | </pre></div> |
michael@0 | 853 | </div> |
michael@0 | 854 | <p>A comparison function for our <cite>Foo</cite> class might look something like this:</p> |
michael@0 | 855 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="k">def</span> <span class="nf">compare</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span> |
michael@0 | 856 | <span class="gp">... </span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">==</span> <span class="nb">type</span><span class="p">(</span><span class="n">other</span><span class="p">):</span> |
michael@0 | 857 | <span class="gp">... </span> <span class="k">return</span> <span class="bp">False</span> |
michael@0 | 858 | <span class="gp">... </span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">a</span> <span class="o">!=</span> <span class="n">other</span><span class="o">.</span><span class="n">a</span><span class="p">:</span> |
michael@0 | 859 | <span class="gp">... </span> <span class="k">return</span> <span class="bp">False</span> |
michael@0 | 860 | <span class="gp">... </span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">b</span> <span class="o">!=</span> <span class="n">other</span><span class="o">.</span><span class="n">b</span><span class="p">:</span> |
michael@0 | 861 | <span class="gp">... </span> <span class="k">return</span> <span class="bp">False</span> |
michael@0 | 862 | <span class="gp">... </span> <span class="k">return</span> <span class="bp">True</span> |
michael@0 | 863 | <span class="gp">...</span> |
michael@0 | 864 | </pre></div> |
michael@0 | 865 | </div> |
michael@0 | 866 | <p>And a matcher object that can use comparison functions like this for its |
michael@0 | 867 | equality operation would look something like this:</p> |
michael@0 | 868 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="k">class</span> <span class="nc">Matcher</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> |
michael@0 | 869 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">compare</span><span class="p">,</span> <span class="n">some_obj</span><span class="p">):</span> |
michael@0 | 870 | <span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">compare</span> <span class="o">=</span> <span class="n">compare</span> |
michael@0 | 871 | <span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">some_obj</span> <span class="o">=</span> <span class="n">some_obj</span> |
michael@0 | 872 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span> |
michael@0 | 873 | <span class="gp">... </span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">compare</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">some_obj</span><span class="p">,</span> <span class="n">other</span><span class="p">)</span> |
michael@0 | 874 | <span class="gp">...</span> |
michael@0 | 875 | </pre></div> |
michael@0 | 876 | </div> |
michael@0 | 877 | <p>Putting all this together:</p> |
michael@0 | 878 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">match_foo</span> <span class="o">=</span> <span class="n">Matcher</span><span class="p">(</span><span class="n">compare</span><span class="p">,</span> <span class="n">Foo</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span> |
michael@0 | 879 | <span class="gp">>>> </span><span class="n">mock</span><span class="o">.</span><span class="n">assert_called_with</span><span class="p">(</span><span class="n">match_foo</span><span class="p">)</span> |
michael@0 | 880 | </pre></div> |
michael@0 | 881 | </div> |
michael@0 | 882 | <p>The <cite>Matcher</cite> is instantiated with our compare function and the <cite>Foo</cite> object |
michael@0 | 883 | we want to compare against. In <cite>assert_called_with</cite> the <cite>Matcher</cite> equality |
michael@0 | 884 | method will be called, which compares the object the mock was called with |
michael@0 | 885 | against the one we created our matcher with. If they match then |
michael@0 | 886 | <cite>assert_called_with</cite> passes, and if they don’t an <cite>AssertionError</cite> is raised:</p> |
michael@0 | 887 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">match_wrong</span> <span class="o">=</span> <span class="n">Matcher</span><span class="p">(</span><span class="n">compare</span><span class="p">,</span> <span class="n">Foo</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">))</span> |
michael@0 | 888 | <span class="gp">>>> </span><span class="n">mock</span><span class="o">.</span><span class="n">assert_called_with</span><span class="p">(</span><span class="n">match_wrong</span><span class="p">)</span> |
michael@0 | 889 | <span class="gt">Traceback (most recent call last):</span> |
michael@0 | 890 | <span class="o">...</span> |
michael@0 | 891 | <span class="gr">AssertionError: Expected</span>: <span class="n">((<Matcher object at 0x...>,), {})</span> |
michael@0 | 892 | <span class="go">Called with: ((<Foo object at 0x...>,), {})</span> |
michael@0 | 893 | </pre></div> |
michael@0 | 894 | </div> |
michael@0 | 895 | <p>With a bit of tweaking you could have the comparison function raise the |
michael@0 | 896 | <cite>AssertionError</cite> directly and provide a more useful failure message.</p> |
michael@0 | 897 | <p>As of version 1.5, the Python testing library <a class="reference external" href="http://pypi.python.org/pypi/PyHamcrest">PyHamcrest</a> provides similar functionality, |
michael@0 | 898 | that may be useful here, in the form of its equality matcher |
michael@0 | 899 | (<a class="reference external" href="http://packages.python.org/PyHamcrest/integration.html#hamcrest.library.integration.match_equality">hamcrest.library.integration.match_equality</a>).</p> |
michael@0 | 900 | </div> |
michael@0 | 901 | <div class="section" id="less-verbose-configuration-of-mock-objects"> |
michael@0 | 902 | <h2>Less verbose configuration of mock objects<a class="headerlink" href="#less-verbose-configuration-of-mock-objects" title="Permalink to this headline">¶</a></h2> |
michael@0 | 903 | <p>This recipe, for easier configuration of mock objects, is now part of <cite>Mock</cite>. |
michael@0 | 904 | See the <a class="reference internal" href="mock.html#mock.Mock.configure_mock" title="mock.Mock.configure_mock"><tt class="xref py py-meth docutils literal"><span class="pre">configure_mock()</span></tt></a> method.</p> |
michael@0 | 905 | </div> |
michael@0 | 906 | <div class="section" id="matching-any-argument-in-assertions"> |
michael@0 | 907 | <h2>Matching any argument in assertions<a class="headerlink" href="#matching-any-argument-in-assertions" title="Permalink to this headline">¶</a></h2> |
michael@0 | 908 | <p>This example is now built in to mock. See <a class="reference internal" href="helpers.html#mock.ANY" title="mock.ANY"><tt class="xref py py-data docutils literal"><span class="pre">ANY</span></tt></a>.</p> |
michael@0 | 909 | </div> |
michael@0 | 910 | <div class="section" id="mocking-properties"> |
michael@0 | 911 | <h2>Mocking Properties<a class="headerlink" href="#mocking-properties" title="Permalink to this headline">¶</a></h2> |
michael@0 | 912 | <p>This example is now built in to mock. See <a class="reference internal" href="mock.html#mock.PropertyMock" title="mock.PropertyMock"><tt class="xref py py-class docutils literal"><span class="pre">PropertyMock</span></tt></a>.</p> |
michael@0 | 913 | </div> |
michael@0 | 914 | <div class="section" id="mocking-open"> |
michael@0 | 915 | <h2>Mocking open<a class="headerlink" href="#mocking-open" title="Permalink to this headline">¶</a></h2> |
michael@0 | 916 | <p>This example is now built in to mock. See <a class="reference internal" href="helpers.html#mock.mock_open" title="mock.mock_open"><tt class="xref py py-func docutils literal"><span class="pre">mock_open()</span></tt></a>.</p> |
michael@0 | 917 | </div> |
michael@0 | 918 | <div class="section" id="mocks-without-some-attributes"> |
michael@0 | 919 | <h2>Mocks without some attributes<a class="headerlink" href="#mocks-without-some-attributes" title="Permalink to this headline">¶</a></h2> |
michael@0 | 920 | <p>This example is now built in to mock. See <a class="reference internal" href="mock.html#deleting-attributes"><em>Deleting Attributes</em></a>.</p> |
michael@0 | 921 | </div> |
michael@0 | 922 | </div> |
michael@0 | 923 | |
michael@0 | 924 | |
michael@0 | 925 | </div> |
michael@0 | 926 | </div> |
michael@0 | 927 | </div> |
michael@0 | 928 | <div class="sphinxsidebar"> |
michael@0 | 929 | <div class="sphinxsidebarwrapper"> |
michael@0 | 930 | <h3><a href="index.html">Table Of Contents</a></h3> |
michael@0 | 931 | <ul> |
michael@0 | 932 | <li><a class="reference internal" href="#">Further Examples</a><ul> |
michael@0 | 933 | <li><a class="reference internal" href="#mocking-chained-calls">Mocking chained calls</a></li> |
michael@0 | 934 | <li><a class="reference internal" href="#partial-mocking">Partial mocking</a></li> |
michael@0 | 935 | <li><a class="reference internal" href="#mocking-a-generator-method">Mocking a Generator Method</a></li> |
michael@0 | 936 | <li><a class="reference internal" href="#applying-the-same-patch-to-every-test-method">Applying the same patch to every test method</a></li> |
michael@0 | 937 | <li><a class="reference internal" href="#mocking-unbound-methods">Mocking Unbound Methods</a></li> |
michael@0 | 938 | <li><a class="reference internal" href="#checking-multiple-calls-with-mock">Checking multiple calls with mock</a></li> |
michael@0 | 939 | <li><a class="reference internal" href="#coping-with-mutable-arguments">Coping with mutable arguments</a></li> |
michael@0 | 940 | <li><a class="reference internal" href="#raising-exceptions-on-attribute-access">Raising exceptions on attribute access</a></li> |
michael@0 | 941 | <li><a class="reference internal" href="#multiple-calls-with-different-effects">Multiple calls with different effects</a></li> |
michael@0 | 942 | <li><a class="reference internal" href="#nesting-patches">Nesting Patches</a></li> |
michael@0 | 943 | <li><a class="reference internal" href="#mocking-a-dictionary-with-magicmock">Mocking a dictionary with MagicMock</a></li> |
michael@0 | 944 | <li><a class="reference internal" href="#mock-subclasses-and-their-attributes">Mock subclasses and their attributes</a></li> |
michael@0 | 945 | <li><a class="reference internal" href="#mocking-imports-with-patch-dict">Mocking imports with patch.dict</a></li> |
michael@0 | 946 | <li><a class="reference internal" href="#tracking-order-of-calls-and-less-verbose-call-assertions">Tracking order of calls and less verbose call assertions</a></li> |
michael@0 | 947 | <li><a class="reference internal" href="#more-complex-argument-matching">More complex argument matching</a></li> |
michael@0 | 948 | <li><a class="reference internal" href="#less-verbose-configuration-of-mock-objects">Less verbose configuration of mock objects</a></li> |
michael@0 | 949 | <li><a class="reference internal" href="#matching-any-argument-in-assertions">Matching any argument in assertions</a></li> |
michael@0 | 950 | <li><a class="reference internal" href="#mocking-properties">Mocking Properties</a></li> |
michael@0 | 951 | <li><a class="reference internal" href="#mocking-open">Mocking open</a></li> |
michael@0 | 952 | <li><a class="reference internal" href="#mocks-without-some-attributes">Mocks without some attributes</a></li> |
michael@0 | 953 | </ul> |
michael@0 | 954 | </li> |
michael@0 | 955 | </ul> |
michael@0 | 956 | |
michael@0 | 957 | <h4>Previous topic</h4> |
michael@0 | 958 | <p class="topless"><a href="getting-started.html" |
michael@0 | 959 | title="previous chapter">Getting Started with Mock</a></p> |
michael@0 | 960 | <h4>Next topic</h4> |
michael@0 | 961 | <p class="topless"><a href="compare.html" |
michael@0 | 962 | title="next chapter">Mock Library Comparison</a></p> |
michael@0 | 963 | <h3>This Page</h3> |
michael@0 | 964 | <ul class="this-page-menu"> |
michael@0 | 965 | <li><a href="_sources/examples.txt" |
michael@0 | 966 | rel="nofollow">Show Source</a></li> |
michael@0 | 967 | </ul> |
michael@0 | 968 | <div id="searchbox" style="display: none"> |
michael@0 | 969 | <h3>Quick search</h3> |
michael@0 | 970 | <form class="search" action="search.html" method="get"> |
michael@0 | 971 | <input type="text" name="q" /> |
michael@0 | 972 | <input type="submit" value="Go" /> |
michael@0 | 973 | <input type="hidden" name="check_keywords" value="yes" /> |
michael@0 | 974 | <input type="hidden" name="area" value="default" /> |
michael@0 | 975 | </form> |
michael@0 | 976 | <p class="searchtip" style="font-size: 90%"> |
michael@0 | 977 | Enter search terms or a module, class or function name. |
michael@0 | 978 | </p> |
michael@0 | 979 | </div> |
michael@0 | 980 | <script type="text/javascript">$('#searchbox').show(0);</script> |
michael@0 | 981 | </div> |
michael@0 | 982 | </div> |
michael@0 | 983 | <div class="clearer"></div> |
michael@0 | 984 | </div> |
michael@0 | 985 | <div class="related"> |
michael@0 | 986 | <h3>Navigation</h3> |
michael@0 | 987 | <ul> |
michael@0 | 988 | <li class="right" style="margin-right: 10px"> |
michael@0 | 989 | <a href="genindex.html" title="General Index" |
michael@0 | 990 | >index</a></li> |
michael@0 | 991 | <li class="right" > |
michael@0 | 992 | <a href="compare.html" title="Mock Library Comparison" |
michael@0 | 993 | >next</a> |</li> |
michael@0 | 994 | <li class="right" > |
michael@0 | 995 | <a href="getting-started.html" title="Getting Started with Mock" |
michael@0 | 996 | >previous</a> |</li> |
michael@0 | 997 | <li><a href="index.html">Mock 1.0.0 documentation</a> »</li> |
michael@0 | 998 | </ul> |
michael@0 | 999 | </div> |
michael@0 | 1000 | <div class="footer"> |
michael@0 | 1001 | © Copyright 2007-2012, Michael Foord & the mock team. |
michael@0 | 1002 | Last updated on Oct 07, 2012. |
michael@0 | 1003 | Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3. |
michael@0 | 1004 | </div> |
michael@0 | 1005 | </body> |
michael@0 | 1006 | </html> |