Wed, 31 Dec 2014 07:22:50 +0100
Correct previous dual key logic pending first delivery installment.
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>Patch Decorators — 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="Helpers" href="helpers.html" /> |
michael@0 | 29 | <link rel="prev" title="The Mock Class" href="mock.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="helpers.html" title="Helpers" |
michael@0 | 40 | accesskey="N">next</a> |</li> |
michael@0 | 41 | <li class="right" > |
michael@0 | 42 | <a href="mock.html" title="The Mock Class" |
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="patch-decorators"> |
michael@0 | 54 | <h1>Patch Decorators<a class="headerlink" href="#patch-decorators" title="Permalink to this headline">¶</a></h1> |
michael@0 | 55 | <p>The patch decorators are used for patching objects only within the scope of |
michael@0 | 56 | the function they decorate. They automatically handle the unpatching for you, |
michael@0 | 57 | even if exceptions are raised. All of these functions can also be used in with |
michael@0 | 58 | statements or as class decorators.</p> |
michael@0 | 59 | <div class="section" id="patch"> |
michael@0 | 60 | <h2>patch<a class="headerlink" href="#patch" title="Permalink to this headline">¶</a></h2> |
michael@0 | 61 | <div class="admonition note"> |
michael@0 | 62 | <p class="first admonition-title">Note</p> |
michael@0 | 63 | <p class="last"><cite>patch</cite> is straightforward to use. The key is to do the patching in the |
michael@0 | 64 | right namespace. See the section <a class="reference internal" href="#id1">where to patch</a>.</p> |
michael@0 | 65 | </div> |
michael@0 | 66 | <dl class="function"> |
michael@0 | 67 | <dt id="mock.patch"> |
michael@0 | 68 | <tt class="descname">patch</tt><big>(</big><em>target</em>, <em>new=DEFAULT</em>, <em>spec=None</em>, <em>create=False</em>, <em>spec_set=None</em>, <em>autospec=None</em>, <em>new_callable=None</em>, <em>**kwargs</em><big>)</big><a class="headerlink" href="#mock.patch" title="Permalink to this definition">¶</a></dt> |
michael@0 | 69 | <dd><p><cite>patch</cite> acts as a function decorator, class decorator or a context |
michael@0 | 70 | manager. Inside the body of the function or with statement, the <cite>target</cite> |
michael@0 | 71 | is patched with a <cite>new</cite> object. When the function/with statement exits |
michael@0 | 72 | the patch is undone.</p> |
michael@0 | 73 | <p>If <cite>new</cite> is omitted, then the target is replaced with a |
michael@0 | 74 | <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>. If <cite>patch</cite> is used as a decorator and <cite>new</cite> is |
michael@0 | 75 | omitted, the created mock is passed in as an extra argument to the |
michael@0 | 76 | decorated function. If <cite>patch</cite> is used as a context manager the created |
michael@0 | 77 | mock is returned by the context manager.</p> |
michael@0 | 78 | <p><cite>target</cite> should be a string in the form <cite>‘package.module.ClassName’</cite>. The |
michael@0 | 79 | <cite>target</cite> is imported and the specified object replaced with the <cite>new</cite> |
michael@0 | 80 | object, so the <cite>target</cite> must be importable from the environment you are |
michael@0 | 81 | calling <cite>patch</cite> from. The target is imported when the decorated function |
michael@0 | 82 | is executed, not at decoration time.</p> |
michael@0 | 83 | <p>The <cite>spec</cite> and <cite>spec_set</cite> keyword arguments are passed to the <cite>MagicMock</cite> |
michael@0 | 84 | if patch is creating one for you.</p> |
michael@0 | 85 | <p>In addition you can pass <cite>spec=True</cite> or <cite>spec_set=True</cite>, which causes |
michael@0 | 86 | patch to pass in the object being mocked as the spec/spec_set object.</p> |
michael@0 | 87 | <p><cite>new_callable</cite> allows you to specify a different class, or callable object, |
michael@0 | 88 | that will be called to create the <cite>new</cite> object. By default <cite>MagicMock</cite> is |
michael@0 | 89 | used.</p> |
michael@0 | 90 | <p>A more powerful form of <cite>spec</cite> is <cite>autospec</cite>. If you set <cite>autospec=True</cite> |
michael@0 | 91 | then the mock with be created with a spec from the object being replaced. |
michael@0 | 92 | All attributes of the mock will also have the spec of the corresponding |
michael@0 | 93 | attribute of the object being replaced. Methods and functions being mocked |
michael@0 | 94 | will have their arguments checked and will raise a <cite>TypeError</cite> if they are |
michael@0 | 95 | called with the wrong signature. For mocks |
michael@0 | 96 | replacing a class, their return value (the ‘instance’) will have the same |
michael@0 | 97 | spec as the class. See the <a class="reference internal" href="helpers.html#mock.create_autospec" title="mock.create_autospec"><tt class="xref py py-func docutils literal"><span class="pre">create_autospec()</span></tt></a> function and |
michael@0 | 98 | <a class="reference internal" href="helpers.html#auto-speccing"><em>Autospeccing</em></a>.</p> |
michael@0 | 99 | <p>Instead of <cite>autospec=True</cite> you can pass <cite>autospec=some_object</cite> to use an |
michael@0 | 100 | arbitrary object as the spec instead of the one being replaced.</p> |
michael@0 | 101 | <p>By default <cite>patch</cite> will fail to replace attributes that don’t exist. If |
michael@0 | 102 | you pass in <cite>create=True</cite>, and the attribute doesn’t exist, patch will |
michael@0 | 103 | create the attribute for you when the patched function is called, and |
michael@0 | 104 | delete it again afterwards. This is useful for writing tests against |
michael@0 | 105 | attributes that your production code creates at runtime. It is off by by |
michael@0 | 106 | default because it can be dangerous. With it switched on you can write |
michael@0 | 107 | passing tests against APIs that don’t actually exist!</p> |
michael@0 | 108 | <p>Patch can be used as a <cite>TestCase</cite> class decorator. It works by |
michael@0 | 109 | decorating each test method in the class. This reduces the boilerplate |
michael@0 | 110 | code when your test methods share a common patchings set. <cite>patch</cite> finds |
michael@0 | 111 | tests by looking for method names that start with <cite>patch.TEST_PREFIX</cite>. |
michael@0 | 112 | By default this is <cite>test</cite>, which matches the way <cite>unittest</cite> finds tests. |
michael@0 | 113 | You can specify an alternative prefix by setting <cite>patch.TEST_PREFIX</cite>.</p> |
michael@0 | 114 | <p>Patch can be used as a context manager, with the with statement. Here the |
michael@0 | 115 | patching applies to the indented block after the with statement. If you |
michael@0 | 116 | use “as” then the patched object will be bound to the name after the |
michael@0 | 117 | “as”; very useful if <cite>patch</cite> is creating a mock object for you.</p> |
michael@0 | 118 | <p><cite>patch</cite> takes arbitrary keyword arguments. These will be passed to |
michael@0 | 119 | the <cite>Mock</cite> (or <cite>new_callable</cite>) on construction.</p> |
michael@0 | 120 | <p><cite>patch.dict(...)</cite>, <cite>patch.multiple(...)</cite> and <cite>patch.object(...)</cite> are |
michael@0 | 121 | available for alternate use-cases.</p> |
michael@0 | 122 | </dd></dl> |
michael@0 | 123 | |
michael@0 | 124 | <p><cite>patch</cite> as function decorator, creating the mock for you and passing it into |
michael@0 | 125 | the decorated function:</p> |
michael@0 | 126 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="nd">@patch</span><span class="p">(</span><span class="s">'__main__.SomeClass'</span><span class="p">)</span> |
michael@0 | 127 | <span class="gp">... </span><span class="k">def</span> <span class="nf">function</span><span class="p">(</span><span class="n">normal_argument</span><span class="p">,</span> <span class="n">mock_class</span><span class="p">):</span> |
michael@0 | 128 | <span class="gp">... </span> <span class="k">print</span> <span class="n">mock_class</span> <span class="ow">is</span> <span class="n">SomeClass</span> |
michael@0 | 129 | <span class="gp">...</span> |
michael@0 | 130 | <span class="gp">>>> </span><span class="n">function</span><span class="p">(</span><span class="bp">None</span><span class="p">)</span> |
michael@0 | 131 | <span class="go">True</span> |
michael@0 | 132 | </pre></div> |
michael@0 | 133 | </div> |
michael@0 | 134 | <p>Patching a class replaces the class with a <cite>MagicMock</cite> <em>instance</em>. If the |
michael@0 | 135 | class is instantiated in the code under test then it will be the |
michael@0 | 136 | <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> of the mock that will be used.</p> |
michael@0 | 137 | <p>If the class is instantiated multiple times you could use |
michael@0 | 138 | <a class="reference internal" href="mock.html#mock.Mock.side_effect" title="mock.Mock.side_effect"><tt class="xref py py-attr docutils literal"><span class="pre">side_effect</span></tt></a> to return a new mock each time. Alternatively you |
michael@0 | 139 | can set the <cite>return_value</cite> to be anything you want.</p> |
michael@0 | 140 | <p>To configure return values on methods of <em>instances</em> on the patched class |
michael@0 | 141 | you must do this on the <cite>return_value</cite>. For example:</p> |
michael@0 | 142 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="k">class</span> <span class="nc">Class</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> |
michael@0 | 143 | <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 | 144 | <span class="gp">... </span> <span class="k">pass</span> |
michael@0 | 145 | <span class="gp">...</span> |
michael@0 | 146 | <span class="gp">>>> </span><span class="k">with</span> <span class="n">patch</span><span class="p">(</span><span class="s">'__main__.Class'</span><span class="p">)</span> <span class="k">as</span> <span class="n">MockClass</span><span class="p">:</span> |
michael@0 | 147 | <span class="gp">... </span> <span class="n">instance</span> <span class="o">=</span> <span class="n">MockClass</span><span class="o">.</span><span class="n">return_value</span> |
michael@0 | 148 | <span class="gp">... </span> <span class="n">instance</span><span class="o">.</span><span class="n">method</span><span class="o">.</span><span class="n">return_value</span> <span class="o">=</span> <span class="s">'foo'</span> |
michael@0 | 149 | <span class="gp">... </span> <span class="k">assert</span> <span class="n">Class</span><span class="p">()</span> <span class="ow">is</span> <span class="n">instance</span> |
michael@0 | 150 | <span class="gp">... </span> <span class="k">assert</span> <span class="n">Class</span><span class="p">()</span><span class="o">.</span><span class="n">method</span><span class="p">()</span> <span class="o">==</span> <span class="s">'foo'</span> |
michael@0 | 151 | <span class="gp">...</span> |
michael@0 | 152 | </pre></div> |
michael@0 | 153 | </div> |
michael@0 | 154 | <p>If you use <cite>spec</cite> or <cite>spec_set</cite> and <cite>patch</cite> is replacing a <em>class</em>, then the |
michael@0 | 155 | return value of the created mock will have the same spec.</p> |
michael@0 | 156 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">Original</span> <span class="o">=</span> <span class="n">Class</span> |
michael@0 | 157 | <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">'__main__.Class'</span><span class="p">,</span> <span class="n">spec</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span> |
michael@0 | 158 | <span class="gp">>>> </span><span class="n">MockClass</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 | 159 | <span class="gp">>>> </span><span class="n">instance</span> <span class="o">=</span> <span class="n">MockClass</span><span class="p">()</span> |
michael@0 | 160 | <span class="gp">>>> </span><span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">instance</span><span class="p">,</span> <span class="n">Original</span><span class="p">)</span> |
michael@0 | 161 | <span class="gp">>>> </span><span class="n">patcher</span><span class="o">.</span><span class="n">stop</span><span class="p">()</span> |
michael@0 | 162 | </pre></div> |
michael@0 | 163 | </div> |
michael@0 | 164 | <p>The <cite>new_callable</cite> argument is useful where you want to use an alternative |
michael@0 | 165 | class to the default <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> for the created mock. For example, if |
michael@0 | 166 | you wanted a <a class="reference internal" href="mock.html#mock.NonCallableMock" title="mock.NonCallableMock"><tt class="xref py py-class docutils literal"><span class="pre">NonCallableMock</span></tt></a> to be used:</p> |
michael@0 | 167 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">thing</span> <span class="o">=</span> <span class="nb">object</span><span class="p">()</span> |
michael@0 | 168 | <span class="gp">>>> </span><span class="k">with</span> <span class="n">patch</span><span class="p">(</span><span class="s">'__main__.thing'</span><span class="p">,</span> <span class="n">new_callable</span><span class="o">=</span><span class="n">NonCallableMock</span><span class="p">)</span> <span class="k">as</span> <span class="n">mock_thing</span><span class="p">:</span> |
michael@0 | 169 | <span class="gp">... </span> <span class="k">assert</span> <span class="n">thing</span> <span class="ow">is</span> <span class="n">mock_thing</span> |
michael@0 | 170 | <span class="gp">... </span> <span class="n">thing</span><span class="p">()</span> |
michael@0 | 171 | <span class="gp">...</span> |
michael@0 | 172 | <span class="gt">Traceback (most recent call last):</span> |
michael@0 | 173 | <span class="c">...</span> |
michael@0 | 174 | <span class="gr">TypeError</span>: <span class="n">'NonCallableMock' object is not callable</span> |
michael@0 | 175 | </pre></div> |
michael@0 | 176 | </div> |
michael@0 | 177 | <p>Another use case might be to replace an object with a <cite>StringIO</cite> instance:</p> |
michael@0 | 178 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">StringIO</span> <span class="kn">import</span> <span class="n">StringIO</span> |
michael@0 | 179 | <span class="gp">>>> </span><span class="k">def</span> <span class="nf">foo</span><span class="p">():</span> |
michael@0 | 180 | <span class="gp">... </span> <span class="k">print</span> <span class="s">'Something'</span> |
michael@0 | 181 | <span class="gp">...</span> |
michael@0 | 182 | <span class="gp">>>> </span><span class="nd">@patch</span><span class="p">(</span><span class="s">'sys.stdout'</span><span class="p">,</span> <span class="n">new_callable</span><span class="o">=</span><span class="n">StringIO</span><span class="p">)</span> |
michael@0 | 183 | <span class="gp">... </span><span class="k">def</span> <span class="nf">test</span><span class="p">(</span><span class="n">mock_stdout</span><span class="p">):</span> |
michael@0 | 184 | <span class="gp">... </span> <span class="n">foo</span><span class="p">()</span> |
michael@0 | 185 | <span class="gp">... </span> <span class="k">assert</span> <span class="n">mock_stdout</span><span class="o">.</span><span class="n">getvalue</span><span class="p">()</span> <span class="o">==</span> <span class="s">'Something</span><span class="se">\n</span><span class="s">'</span> |
michael@0 | 186 | <span class="gp">...</span> |
michael@0 | 187 | <span class="gp">>>> </span><span class="n">test</span><span class="p">()</span> |
michael@0 | 188 | </pre></div> |
michael@0 | 189 | </div> |
michael@0 | 190 | <p>When <cite>patch</cite> is creating a mock for you, it is common that the first thing |
michael@0 | 191 | you need to do is to configure the mock. Some of that configuration can be done |
michael@0 | 192 | in the call to patch. Any arbitrary keywords you pass into the call will be |
michael@0 | 193 | used to set attributes on the created mock:</p> |
michael@0 | 194 | <div class="highlight-python"><div class="highlight"><pre><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">'__main__.thing'</span><span class="p">,</span> <span class="n">first</span><span class="o">=</span><span class="s">'one'</span><span class="p">,</span> <span class="n">second</span><span class="o">=</span><span class="s">'two'</span><span class="p">)</span> |
michael@0 | 195 | <span class="gp">>>> </span><span class="n">mock_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 | 196 | <span class="gp">>>> </span><span class="n">mock_thing</span><span class="o">.</span><span class="n">first</span> |
michael@0 | 197 | <span class="go">'one'</span> |
michael@0 | 198 | <span class="gp">>>> </span><span class="n">mock_thing</span><span class="o">.</span><span class="n">second</span> |
michael@0 | 199 | <span class="go">'two'</span> |
michael@0 | 200 | </pre></div> |
michael@0 | 201 | </div> |
michael@0 | 202 | <p>As well as attributes on the created mock attributes, like the |
michael@0 | 203 | <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> and <a class="reference internal" href="mock.html#mock.Mock.side_effect" title="mock.Mock.side_effect"><tt class="xref py py-attr docutils literal"><span class="pre">side_effect</span></tt></a>, of child mocks can |
michael@0 | 204 | also be configured. These aren’t syntactically valid to pass in directly as |
michael@0 | 205 | keyword arguments, but a dictionary with these as keys can still be expanded |
michael@0 | 206 | into a <cite>patch</cite> call using <cite>**</cite>:</p> |
michael@0 | 207 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">config</span> <span class="o">=</span> <span class="p">{</span><span class="s">'method.return_value'</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span> <span class="s">'other.side_effect'</span><span class="p">:</span> <span class="ne">KeyError</span><span class="p">}</span> |
michael@0 | 208 | <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">'__main__.thing'</span><span class="p">,</span> <span class="o">**</span><span class="n">config</span><span class="p">)</span> |
michael@0 | 209 | <span class="gp">>>> </span><span class="n">mock_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 | 210 | <span class="gp">>>> </span><span class="n">mock_thing</span><span class="o">.</span><span class="n">method</span><span class="p">()</span> |
michael@0 | 211 | <span class="go">3</span> |
michael@0 | 212 | <span class="gp">>>> </span><span class="n">mock_thing</span><span class="o">.</span><span class="n">other</span><span class="p">()</span> |
michael@0 | 213 | <span class="gt">Traceback (most recent call last):</span> |
michael@0 | 214 | <span class="c">...</span> |
michael@0 | 215 | <span class="gr">KeyError</span> |
michael@0 | 216 | </pre></div> |
michael@0 | 217 | </div> |
michael@0 | 218 | </div> |
michael@0 | 219 | <div class="section" id="patch-object"> |
michael@0 | 220 | <h2>patch.object<a class="headerlink" href="#patch-object" title="Permalink to this headline">¶</a></h2> |
michael@0 | 221 | <dl class="function"> |
michael@0 | 222 | <dt id="mock.patch.object"> |
michael@0 | 223 | <tt class="descclassname">patch.</tt><tt class="descname">object</tt><big>(</big><em>target</em>, <em>attribute</em>, <em>new=DEFAULT</em>, <em>spec=None</em>, <em>create=False</em>, <em>spec_set=None</em>, <em>autospec=None</em>, <em>new_callable=None</em>, <em>**kwargs</em><big>)</big><a class="headerlink" href="#mock.patch.object" title="Permalink to this definition">¶</a></dt> |
michael@0 | 224 | <dd><p>patch the named member (<cite>attribute</cite>) on an object (<cite>target</cite>) with a mock |
michael@0 | 225 | object.</p> |
michael@0 | 226 | <p><cite>patch.object</cite> can be used as a decorator, class decorator or a context |
michael@0 | 227 | manager. Arguments <cite>new</cite>, <cite>spec</cite>, <cite>create</cite>, <cite>spec_set</cite>, <cite>autospec</cite> and |
michael@0 | 228 | <cite>new_callable</cite> have the same meaning as for <cite>patch</cite>. Like <cite>patch</cite>, |
michael@0 | 229 | <cite>patch.object</cite> takes arbitrary keyword arguments for configuring the mock |
michael@0 | 230 | object it creates.</p> |
michael@0 | 231 | <p>When used as a class decorator <cite>patch.object</cite> honours <cite>patch.TEST_PREFIX</cite> |
michael@0 | 232 | for choosing which methods to wrap.</p> |
michael@0 | 233 | </dd></dl> |
michael@0 | 234 | |
michael@0 | 235 | <p>You can either call <cite>patch.object</cite> with three arguments or two arguments. The |
michael@0 | 236 | three argument form takes the object to be patched, the attribute name and the |
michael@0 | 237 | object to replace the attribute with.</p> |
michael@0 | 238 | <p>When calling with the two argument form you omit the replacement object, and a |
michael@0 | 239 | mock is created for you and passed in as an extra argument to the decorated |
michael@0 | 240 | function:</p> |
michael@0 | 241 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="nd">@patch.object</span><span class="p">(</span><span class="n">SomeClass</span><span class="p">,</span> <span class="s">'class_method'</span><span class="p">)</span> |
michael@0 | 242 | <span class="gp">... </span><span class="k">def</span> <span class="nf">test</span><span class="p">(</span><span class="n">mock_method</span><span class="p">):</span> |
michael@0 | 243 | <span class="gp">... </span> <span class="n">SomeClass</span><span class="o">.</span><span class="n">class_method</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span> |
michael@0 | 244 | <span class="gp">... </span> <span class="n">mock_method</span><span class="o">.</span><span class="n">assert_called_with</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span> |
michael@0 | 245 | <span class="gp">...</span> |
michael@0 | 246 | <span class="gp">>>> </span><span class="n">test</span><span class="p">()</span> |
michael@0 | 247 | </pre></div> |
michael@0 | 248 | </div> |
michael@0 | 249 | <p><cite>spec</cite>, <cite>create</cite> and the other arguments to <cite>patch.object</cite> have the same |
michael@0 | 250 | meaning as they do for <cite>patch</cite>.</p> |
michael@0 | 251 | </div> |
michael@0 | 252 | <div class="section" id="patch-dict"> |
michael@0 | 253 | <h2>patch.dict<a class="headerlink" href="#patch-dict" title="Permalink to this headline">¶</a></h2> |
michael@0 | 254 | <dl class="function"> |
michael@0 | 255 | <dt id="mock.patch.dict"> |
michael@0 | 256 | <tt class="descclassname">patch.</tt><tt class="descname">dict</tt><big>(</big><em>in_dict</em>, <em>values=()</em>, <em>clear=False</em>, <em>**kwargs</em><big>)</big><a class="headerlink" href="#mock.patch.dict" title="Permalink to this definition">¶</a></dt> |
michael@0 | 257 | <dd><p>Patch a dictionary, or dictionary like object, and restore the dictionary |
michael@0 | 258 | to its original state after the test.</p> |
michael@0 | 259 | <p><cite>in_dict</cite> can be a dictionary or a mapping like container. If it is a |
michael@0 | 260 | mapping then it must at least support getting, setting and deleting items |
michael@0 | 261 | plus iterating over keys.</p> |
michael@0 | 262 | <p><cite>in_dict</cite> can also be a string specifying the name of the dictionary, which |
michael@0 | 263 | will then be fetched by importing it.</p> |
michael@0 | 264 | <p><cite>values</cite> can be a dictionary of values to set in the dictionary. <cite>values</cite> |
michael@0 | 265 | can also be an iterable of <cite>(key, value)</cite> pairs.</p> |
michael@0 | 266 | <p>If <cite>clear</cite> is True then the dictionary will be cleared before the new |
michael@0 | 267 | values are set.</p> |
michael@0 | 268 | <p><cite>patch.dict</cite> can also be called with arbitrary keyword arguments to set |
michael@0 | 269 | values in the dictionary.</p> |
michael@0 | 270 | <p><cite>patch.dict</cite> can be used as a context manager, decorator or class |
michael@0 | 271 | decorator. When used as a class decorator <cite>patch.dict</cite> honours |
michael@0 | 272 | <cite>patch.TEST_PREFIX</cite> for choosing which methods to wrap.</p> |
michael@0 | 273 | </dd></dl> |
michael@0 | 274 | |
michael@0 | 275 | <p><cite>patch.dict</cite> can be used to add members to a dictionary, or simply let a test |
michael@0 | 276 | change a dictionary, and ensure the dictionary is restored when the test |
michael@0 | 277 | ends.</p> |
michael@0 | 278 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">mock</span> <span class="kn">import</span> <span class="n">patch</span> |
michael@0 | 279 | <span class="gp">>>> </span><span class="n">foo</span> <span class="o">=</span> <span class="p">{}</span> |
michael@0 | 280 | <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="n">foo</span><span class="p">,</span> <span class="p">{</span><span class="s">'newkey'</span><span class="p">:</span> <span class="s">'newvalue'</span><span class="p">}):</span> |
michael@0 | 281 | <span class="gp">... </span> <span class="k">assert</span> <span class="n">foo</span> <span class="o">==</span> <span class="p">{</span><span class="s">'newkey'</span><span class="p">:</span> <span class="s">'newvalue'</span><span class="p">}</span> |
michael@0 | 282 | <span class="gp">...</span> |
michael@0 | 283 | <span class="gp">>>> </span><span class="k">assert</span> <span class="n">foo</span> <span class="o">==</span> <span class="p">{}</span> |
michael@0 | 284 | |
michael@0 | 285 | <span class="gp">>>> </span><span class="kn">import</span> <span class="nn">os</span> |
michael@0 | 286 | <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">'os.environ'</span><span class="p">,</span> <span class="p">{</span><span class="s">'newkey'</span><span class="p">:</span> <span class="s">'newvalue'</span><span class="p">}):</span> |
michael@0 | 287 | <span class="gp">... </span> <span class="k">print</span> <span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s">'newkey'</span><span class="p">]</span> |
michael@0 | 288 | <span class="gp">...</span> |
michael@0 | 289 | <span class="go">newvalue</span> |
michael@0 | 290 | <span class="gp">>>> </span><span class="k">assert</span> <span class="s">'newkey'</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">os</span><span class="o">.</span><span class="n">environ</span> |
michael@0 | 291 | </pre></div> |
michael@0 | 292 | </div> |
michael@0 | 293 | <p>Keywords can be used in the <cite>patch.dict</cite> call to set values in the dictionary:</p> |
michael@0 | 294 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">mymodule</span> <span class="o">=</span> <span class="n">MagicMock</span><span class="p">()</span> |
michael@0 | 295 | <span class="gp">>>> </span><span class="n">mymodule</span><span class="o">.</span><span class="n">function</span><span class="o">.</span><span class="n">return_value</span> <span class="o">=</span> <span class="s">'fish'</span> |
michael@0 | 296 | <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">mymodule</span><span class="o">=</span><span class="n">mymodule</span><span class="p">):</span> |
michael@0 | 297 | <span class="gp">... </span> <span class="kn">import</span> <span class="nn">mymodule</span> |
michael@0 | 298 | <span class="gp">... </span> <span class="n">mymodule</span><span class="o">.</span><span class="n">function</span><span class="p">(</span><span class="s">'some'</span><span class="p">,</span> <span class="s">'args'</span><span class="p">)</span> |
michael@0 | 299 | <span class="gp">...</span> |
michael@0 | 300 | <span class="go">'fish'</span> |
michael@0 | 301 | </pre></div> |
michael@0 | 302 | </div> |
michael@0 | 303 | <p><cite>patch.dict</cite> can be used with dictionary like objects that aren’t actually |
michael@0 | 304 | dictionaries. At the very minimum they must support item getting, setting, |
michael@0 | 305 | deleting and either iteration or membership test. This corresponds to the |
michael@0 | 306 | magic methods <cite>__getitem__</cite>, <cite>__setitem__</cite>, <cite>__delitem__</cite> and either |
michael@0 | 307 | <cite>__iter__</cite> or <cite>__contains__</cite>.</p> |
michael@0 | 308 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="k">class</span> <span class="nc">Container</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> |
michael@0 | 309 | <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 | 310 | <span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">values</span> <span class="o">=</span> <span class="p">{}</span> |
michael@0 | 311 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">__getitem__</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 | 312 | <span class="gp">... </span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">values</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> |
michael@0 | 313 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">__setitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span> |
michael@0 | 314 | <span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">values</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> |
michael@0 | 315 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">__delitem__</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 | 316 | <span class="gp">... </span> <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">values</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> |
michael@0 | 317 | <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 | 318 | <span class="gp">... </span> <span class="k">return</span> <span class="nb">iter</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">values</span><span class="p">)</span> |
michael@0 | 319 | <span class="gp">...</span> |
michael@0 | 320 | <span class="gp">>>> </span><span class="n">thing</span> <span class="o">=</span> <span class="n">Container</span><span class="p">()</span> |
michael@0 | 321 | <span class="gp">>>> </span><span class="n">thing</span><span class="p">[</span><span class="s">'one'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span> |
michael@0 | 322 | <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="n">thing</span><span class="p">,</span> <span class="n">one</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="n">two</span><span class="o">=</span><span class="mi">3</span><span class="p">):</span> |
michael@0 | 323 | <span class="gp">... </span> <span class="k">assert</span> <span class="n">thing</span><span class="p">[</span><span class="s">'one'</span><span class="p">]</span> <span class="o">==</span> <span class="mi">2</span> |
michael@0 | 324 | <span class="gp">... </span> <span class="k">assert</span> <span class="n">thing</span><span class="p">[</span><span class="s">'two'</span><span class="p">]</span> <span class="o">==</span> <span class="mi">3</span> |
michael@0 | 325 | <span class="gp">...</span> |
michael@0 | 326 | <span class="gp">>>> </span><span class="k">assert</span> <span class="n">thing</span><span class="p">[</span><span class="s">'one'</span><span class="p">]</span> <span class="o">==</span> <span class="mi">1</span> |
michael@0 | 327 | <span class="gp">>>> </span><span class="k">assert</span> <span class="nb">list</span><span class="p">(</span><span class="n">thing</span><span class="p">)</span> <span class="o">==</span> <span class="p">[</span><span class="s">'one'</span><span class="p">]</span> |
michael@0 | 328 | </pre></div> |
michael@0 | 329 | </div> |
michael@0 | 330 | </div> |
michael@0 | 331 | <div class="section" id="patch-multiple"> |
michael@0 | 332 | <h2>patch.multiple<a class="headerlink" href="#patch-multiple" title="Permalink to this headline">¶</a></h2> |
michael@0 | 333 | <dl class="function"> |
michael@0 | 334 | <dt id="mock.patch.multiple"> |
michael@0 | 335 | <tt class="descclassname">patch.</tt><tt class="descname">multiple</tt><big>(</big><em>target</em>, <em>spec=None</em>, <em>create=False</em>, <em>spec_set=None</em>, <em>autospec=None</em>, <em>new_callable=None</em>, <em>**kwargs</em><big>)</big><a class="headerlink" href="#mock.patch.multiple" title="Permalink to this definition">¶</a></dt> |
michael@0 | 336 | <dd><p>Perform multiple patches in a single call. It takes the object to be |
michael@0 | 337 | patched (either as an object or a string to fetch the object by importing) |
michael@0 | 338 | and keyword arguments for the patches:</p> |
michael@0 | 339 | <div class="highlight-python"><div class="highlight"><pre><span class="k">with</span> <span class="n">patch</span><span class="o">.</span><span class="n">multiple</span><span class="p">(</span><span class="n">settings</span><span class="p">,</span> <span class="n">FIRST_PATCH</span><span class="o">=</span><span class="s">'one'</span><span class="p">,</span> <span class="n">SECOND_PATCH</span><span class="o">=</span><span class="s">'two'</span><span class="p">):</span> |
michael@0 | 340 | <span class="o">...</span> |
michael@0 | 341 | </pre></div> |
michael@0 | 342 | </div> |
michael@0 | 343 | <p>Use <a class="reference internal" href="sentinel.html#mock.DEFAULT" title="mock.DEFAULT"><tt class="xref py py-data docutils literal"><span class="pre">DEFAULT</span></tt></a> as the value if you want <cite>patch.multiple</cite> to create |
michael@0 | 344 | mocks for you. In this case the created mocks are passed into a decorated |
michael@0 | 345 | function by keyword, and a dictionary is returned when <cite>patch.multiple</cite> is |
michael@0 | 346 | used as a context manager.</p> |
michael@0 | 347 | <p><cite>patch.multiple</cite> can be used as a decorator, class decorator or a context |
michael@0 | 348 | manager. The arguments <cite>spec</cite>, <cite>spec_set</cite>, <cite>create</cite>, <cite>autospec</cite> and |
michael@0 | 349 | <cite>new_callable</cite> have the same meaning as for <cite>patch</cite>. These arguments will |
michael@0 | 350 | be applied to <em>all</em> patches done by <cite>patch.multiple</cite>.</p> |
michael@0 | 351 | <p>When used as a class decorator <cite>patch.multiple</cite> honours <cite>patch.TEST_PREFIX</cite> |
michael@0 | 352 | for choosing which methods to wrap.</p> |
michael@0 | 353 | </dd></dl> |
michael@0 | 354 | |
michael@0 | 355 | <p>If you want <cite>patch.multiple</cite> to create mocks for you, then you can use |
michael@0 | 356 | <a class="reference internal" href="sentinel.html#mock.DEFAULT" title="mock.DEFAULT"><tt class="xref py py-data docutils literal"><span class="pre">DEFAULT</span></tt></a> as the value. If you use <cite>patch.multiple</cite> as a decorator |
michael@0 | 357 | then the created mocks are passed into the decorated function by keyword.</p> |
michael@0 | 358 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">thing</span> <span class="o">=</span> <span class="nb">object</span><span class="p">()</span> |
michael@0 | 359 | <span class="gp">>>> </span><span class="n">other</span> <span class="o">=</span> <span class="nb">object</span><span class="p">()</span> |
michael@0 | 360 | |
michael@0 | 361 | <span class="gp">>>> </span><span class="nd">@patch.multiple</span><span class="p">(</span><span class="s">'__main__'</span><span class="p">,</span> <span class="n">thing</span><span class="o">=</span><span class="n">DEFAULT</span><span class="p">,</span> <span class="n">other</span><span class="o">=</span><span class="n">DEFAULT</span><span class="p">)</span> |
michael@0 | 362 | <span class="gp">... </span><span class="k">def</span> <span class="nf">test_function</span><span class="p">(</span><span class="n">thing</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span> |
michael@0 | 363 | <span class="gp">... </span> <span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">thing</span><span class="p">,</span> <span class="n">MagicMock</span><span class="p">)</span> |
michael@0 | 364 | <span class="gp">... </span> <span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">MagicMock</span><span class="p">)</span> |
michael@0 | 365 | <span class="gp">...</span> |
michael@0 | 366 | <span class="gp">>>> </span><span class="n">test_function</span><span class="p">()</span> |
michael@0 | 367 | </pre></div> |
michael@0 | 368 | </div> |
michael@0 | 369 | <p><cite>patch.multiple</cite> can be nested with other <cite>patch</cite> decorators, but put arguments |
michael@0 | 370 | passed by keyword <em>after</em> any of the standard arguments created by <cite>patch</cite>:</p> |
michael@0 | 371 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="nd">@patch</span><span class="p">(</span><span class="s">'sys.exit'</span><span class="p">)</span> |
michael@0 | 372 | <span class="gp">... </span><span class="nd">@patch.multiple</span><span class="p">(</span><span class="s">'__main__'</span><span class="p">,</span> <span class="n">thing</span><span class="o">=</span><span class="n">DEFAULT</span><span class="p">,</span> <span class="n">other</span><span class="o">=</span><span class="n">DEFAULT</span><span class="p">)</span> |
michael@0 | 373 | <span class="gp">... </span><span class="k">def</span> <span class="nf">test_function</span><span class="p">(</span><span class="n">mock_exit</span><span class="p">,</span> <span class="n">other</span><span class="p">,</span> <span class="n">thing</span><span class="p">):</span> |
michael@0 | 374 | <span class="gp">... </span> <span class="k">assert</span> <span class="s">'other'</span> <span class="ow">in</span> <span class="nb">repr</span><span class="p">(</span><span class="n">other</span><span class="p">)</span> |
michael@0 | 375 | <span class="gp">... </span> <span class="k">assert</span> <span class="s">'thing'</span> <span class="ow">in</span> <span class="nb">repr</span><span class="p">(</span><span class="n">thing</span><span class="p">)</span> |
michael@0 | 376 | <span class="gp">... </span> <span class="k">assert</span> <span class="s">'exit'</span> <span class="ow">in</span> <span class="nb">repr</span><span class="p">(</span><span class="n">mock_exit</span><span class="p">)</span> |
michael@0 | 377 | <span class="gp">...</span> |
michael@0 | 378 | <span class="gp">>>> </span><span class="n">test_function</span><span class="p">()</span> |
michael@0 | 379 | </pre></div> |
michael@0 | 380 | </div> |
michael@0 | 381 | <p>If <cite>patch.multiple</cite> is used as a context manager, the value returned by the |
michael@0 | 382 | context manger is a dictionary where created mocks are keyed by name:</p> |
michael@0 | 383 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="k">with</span> <span class="n">patch</span><span class="o">.</span><span class="n">multiple</span><span class="p">(</span><span class="s">'__main__'</span><span class="p">,</span> <span class="n">thing</span><span class="o">=</span><span class="n">DEFAULT</span><span class="p">,</span> <span class="n">other</span><span class="o">=</span><span class="n">DEFAULT</span><span class="p">)</span> <span class="k">as</span> <span class="n">values</span><span class="p">:</span> |
michael@0 | 384 | <span class="gp">... </span> <span class="k">assert</span> <span class="s">'other'</span> <span class="ow">in</span> <span class="nb">repr</span><span class="p">(</span><span class="n">values</span><span class="p">[</span><span class="s">'other'</span><span class="p">])</span> |
michael@0 | 385 | <span class="gp">... </span> <span class="k">assert</span> <span class="s">'thing'</span> <span class="ow">in</span> <span class="nb">repr</span><span class="p">(</span><span class="n">values</span><span class="p">[</span><span class="s">'thing'</span><span class="p">])</span> |
michael@0 | 386 | <span class="gp">... </span> <span class="k">assert</span> <span class="n">values</span><span class="p">[</span><span class="s">'thing'</span><span class="p">]</span> <span class="ow">is</span> <span class="n">thing</span> |
michael@0 | 387 | <span class="gp">... </span> <span class="k">assert</span> <span class="n">values</span><span class="p">[</span><span class="s">'other'</span><span class="p">]</span> <span class="ow">is</span> <span class="n">other</span> |
michael@0 | 388 | <span class="gp">...</span> |
michael@0 | 389 | </pre></div> |
michael@0 | 390 | </div> |
michael@0 | 391 | </div> |
michael@0 | 392 | <div class="section" id="patch-methods-start-and-stop"> |
michael@0 | 393 | <span id="start-and-stop"></span><h2>patch methods: start and stop<a class="headerlink" href="#patch-methods-start-and-stop" title="Permalink to this headline">¶</a></h2> |
michael@0 | 394 | <p>All the patchers have <cite>start</cite> and <cite>stop</cite> methods. These make it simpler to do |
michael@0 | 395 | patching in <cite>setUp</cite> methods or where you want to do multiple patches without |
michael@0 | 396 | nesting decorators or with statements.</p> |
michael@0 | 397 | <p>To use them call <cite>patch</cite>, <cite>patch.object</cite> or <cite>patch.dict</cite> as normal and keep a |
michael@0 | 398 | reference to the returned <cite>patcher</cite> object. You can then call <cite>start</cite> to put |
michael@0 | 399 | the patch in place and <cite>stop</cite> to undo it.</p> |
michael@0 | 400 | <p>If you are using <cite>patch</cite> to create a mock for you then it will be returned by |
michael@0 | 401 | the call to <cite>patcher.start</cite>.</p> |
michael@0 | 402 | <div class="highlight-python"><div class="highlight"><pre><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">'package.module.ClassName'</span><span class="p">)</span> |
michael@0 | 403 | <span class="gp">>>> </span><span class="kn">from</span> <span class="nn">package</span> <span class="kn">import</span> <span class="n">module</span> |
michael@0 | 404 | <span class="gp">>>> </span><span class="n">original</span> <span class="o">=</span> <span class="n">module</span><span class="o">.</span><span class="n">ClassName</span> |
michael@0 | 405 | <span class="gp">>>> </span><span class="n">new_mock</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 | 406 | <span class="gp">>>> </span><span class="k">assert</span> <span class="n">module</span><span class="o">.</span><span class="n">ClassName</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">original</span> |
michael@0 | 407 | <span class="gp">>>> </span><span class="k">assert</span> <span class="n">module</span><span class="o">.</span><span class="n">ClassName</span> <span class="ow">is</span> <span class="n">new_mock</span> |
michael@0 | 408 | <span class="gp">>>> </span><span class="n">patcher</span><span class="o">.</span><span class="n">stop</span><span class="p">()</span> |
michael@0 | 409 | <span class="gp">>>> </span><span class="k">assert</span> <span class="n">module</span><span class="o">.</span><span class="n">ClassName</span> <span class="ow">is</span> <span class="n">original</span> |
michael@0 | 410 | <span class="gp">>>> </span><span class="k">assert</span> <span class="n">module</span><span class="o">.</span><span class="n">ClassName</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">new_mock</span> |
michael@0 | 411 | </pre></div> |
michael@0 | 412 | </div> |
michael@0 | 413 | <p>A typical use case for this might be for doing multiple patches in the <cite>setUp</cite> |
michael@0 | 414 | method of a <cite>TestCase</cite>:</p> |
michael@0 | 415 | <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 | 416 | <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 | 417 | <span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">patcher1</span> <span class="o">=</span> <span class="n">patch</span><span class="p">(</span><span class="s">'package.module.Class1'</span><span class="p">)</span> |
michael@0 | 418 | <span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">patcher2</span> <span class="o">=</span> <span class="n">patch</span><span class="p">(</span><span class="s">'package.module.Class2'</span><span class="p">)</span> |
michael@0 | 419 | <span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">MockClass1</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">patcher1</span><span class="o">.</span><span class="n">start</span><span class="p">()</span> |
michael@0 | 420 | <span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">MockClass2</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">patcher2</span><span class="o">.</span><span class="n">start</span><span class="p">()</span> |
michael@0 | 421 | <span class="gp">...</span> |
michael@0 | 422 | <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 | 423 | <span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">patcher1</span><span class="o">.</span><span class="n">stop</span><span class="p">()</span> |
michael@0 | 424 | <span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">patcher2</span><span class="o">.</span><span class="n">stop</span><span class="p">()</span> |
michael@0 | 425 | <span class="gp">...</span> |
michael@0 | 426 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">test_something</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
michael@0 | 427 | <span class="gp">... </span> <span class="k">assert</span> <span class="n">package</span><span class="o">.</span><span class="n">module</span><span class="o">.</span><span class="n">Class1</span> <span class="ow">is</span> <span class="bp">self</span><span class="o">.</span><span class="n">MockClass1</span> |
michael@0 | 428 | <span class="gp">... </span> <span class="k">assert</span> <span class="n">package</span><span class="o">.</span><span class="n">module</span><span class="o">.</span><span class="n">Class2</span> <span class="ow">is</span> <span class="bp">self</span><span class="o">.</span><span class="n">MockClass2</span> |
michael@0 | 429 | <span class="gp">...</span> |
michael@0 | 430 | <span class="gp">>>> </span><span class="n">MyTest</span><span class="p">(</span><span class="s">'test_something'</span><span class="p">)</span><span class="o">.</span><span class="n">run</span><span class="p">()</span> |
michael@0 | 431 | </pre></div> |
michael@0 | 432 | </div> |
michael@0 | 433 | <div class="admonition caution"> |
michael@0 | 434 | <p class="first admonition-title">Caution</p> |
michael@0 | 435 | <p>If you use this technique you must ensure that the patching is “undone” by |
michael@0 | 436 | calling <cite>stop</cite>. This can be fiddlier than you might think, because if an |
michael@0 | 437 | 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 |
michael@0 | 438 | easier.</p> |
michael@0 | 439 | <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 | 440 | <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 | 441 | <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">'package.module.Class'</span><span class="p">)</span> |
michael@0 | 442 | <span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">MockClass</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 | 443 | <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 | 444 | <span class="gp">...</span> |
michael@0 | 445 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">test_something</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
michael@0 | 446 | <span class="gp">... </span> <span class="k">assert</span> <span class="n">package</span><span class="o">.</span><span class="n">module</span><span class="o">.</span><span class="n">Class</span> <span class="ow">is</span> <span class="bp">self</span><span class="o">.</span><span class="n">MockClass</span> |
michael@0 | 447 | <span class="gp">...</span> |
michael@0 | 448 | <span class="gp">>>> </span><span class="n">MyTest</span><span class="p">(</span><span class="s">'test_something'</span><span class="p">)</span><span class="o">.</span><span class="n">run</span><span class="p">()</span> |
michael@0 | 449 | </pre></div> |
michael@0 | 450 | </div> |
michael@0 | 451 | <p class="last">As an added bonus you no longer need to keep a reference to the <cite>patcher</cite> |
michael@0 | 452 | object.</p> |
michael@0 | 453 | </div> |
michael@0 | 454 | <p>It is also possible to stop all patches which have been started by using |
michael@0 | 455 | <cite>patch.stopall</cite>.</p> |
michael@0 | 456 | <dl class="function"> |
michael@0 | 457 | <dt id="mock.patch.stopall"> |
michael@0 | 458 | <tt class="descclassname">patch.</tt><tt class="descname">stopall</tt><big>(</big><big>)</big><a class="headerlink" href="#mock.patch.stopall" title="Permalink to this definition">¶</a></dt> |
michael@0 | 459 | <dd><p>Stop all active patches. Only stops patches started with <cite>start</cite>.</p> |
michael@0 | 460 | </dd></dl> |
michael@0 | 461 | |
michael@0 | 462 | </div> |
michael@0 | 463 | <div class="section" id="test-prefix"> |
michael@0 | 464 | <h2>TEST_PREFIX<a class="headerlink" href="#test-prefix" title="Permalink to this headline">¶</a></h2> |
michael@0 | 465 | <p>All of the patchers can be used as class decorators. When used in this way |
michael@0 | 466 | they wrap every test method on the class. The patchers recognise methods that |
michael@0 | 467 | start with <cite>test</cite> as being test methods. This is the same way that the |
michael@0 | 468 | <cite>unittest.TestLoader</cite> finds test methods by default.</p> |
michael@0 | 469 | <p>It is possible that you want to use a different prefix for your tests. You can |
michael@0 | 470 | inform the patchers of the different prefix by setting <cite>patch.TEST_PREFIX</cite>:</p> |
michael@0 | 471 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">patch</span><span class="o">.</span><span class="n">TEST_PREFIX</span> <span class="o">=</span> <span class="s">'foo'</span> |
michael@0 | 472 | <span class="gp">>>> </span><span class="n">value</span> <span class="o">=</span> <span class="mi">3</span> |
michael@0 | 473 | <span class="go">>>></span> |
michael@0 | 474 | <span class="gp">>>> </span><span class="nd">@patch</span><span class="p">(</span><span class="s">'__main__.value'</span><span class="p">,</span> <span class="s">'not three'</span><span class="p">)</span> |
michael@0 | 475 | <span class="gp">... </span><span class="k">class</span> <span class="nc">Thing</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> |
michael@0 | 476 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">foo_one</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
michael@0 | 477 | <span class="gp">... </span> <span class="k">print</span> <span class="n">value</span> |
michael@0 | 478 | <span class="gp">... </span> <span class="k">def</span> <span class="nf">foo_two</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
michael@0 | 479 | <span class="gp">... </span> <span class="k">print</span> <span class="n">value</span> |
michael@0 | 480 | <span class="gp">...</span> |
michael@0 | 481 | <span class="go">>>></span> |
michael@0 | 482 | <span class="gp">>>> </span><span class="n">Thing</span><span class="p">()</span><span class="o">.</span><span class="n">foo_one</span><span class="p">()</span> |
michael@0 | 483 | <span class="go">not three</span> |
michael@0 | 484 | <span class="gp">>>> </span><span class="n">Thing</span><span class="p">()</span><span class="o">.</span><span class="n">foo_two</span><span class="p">()</span> |
michael@0 | 485 | <span class="go">not three</span> |
michael@0 | 486 | <span class="gp">>>> </span><span class="n">value</span> |
michael@0 | 487 | <span class="go">3</span> |
michael@0 | 488 | </pre></div> |
michael@0 | 489 | </div> |
michael@0 | 490 | </div> |
michael@0 | 491 | <div class="section" id="nesting-patch-decorators"> |
michael@0 | 492 | <h2>Nesting Patch Decorators<a class="headerlink" href="#nesting-patch-decorators" title="Permalink to this headline">¶</a></h2> |
michael@0 | 493 | <p>If you want to perform multiple patches then you can simply stack up the |
michael@0 | 494 | decorators.</p> |
michael@0 | 495 | <p>You can stack up multiple patch decorators using this pattern:</p> |
michael@0 | 496 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="nd">@patch.object</span><span class="p">(</span><span class="n">SomeClass</span><span class="p">,</span> <span class="s">'class_method'</span><span class="p">)</span> |
michael@0 | 497 | <span class="gp">... </span><span class="nd">@patch.object</span><span class="p">(</span><span class="n">SomeClass</span><span class="p">,</span> <span class="s">'static_method'</span><span class="p">)</span> |
michael@0 | 498 | <span class="gp">... </span><span class="k">def</span> <span class="nf">test</span><span class="p">(</span><span class="n">mock1</span><span class="p">,</span> <span class="n">mock2</span><span class="p">):</span> |
michael@0 | 499 | <span class="gp">... </span> <span class="k">assert</span> <span class="n">SomeClass</span><span class="o">.</span><span class="n">static_method</span> <span class="ow">is</span> <span class="n">mock1</span> |
michael@0 | 500 | <span class="gp">... </span> <span class="k">assert</span> <span class="n">SomeClass</span><span class="o">.</span><span class="n">class_method</span> <span class="ow">is</span> <span class="n">mock2</span> |
michael@0 | 501 | <span class="gp">... </span> <span class="n">SomeClass</span><span class="o">.</span><span class="n">static_method</span><span class="p">(</span><span class="s">'foo'</span><span class="p">)</span> |
michael@0 | 502 | <span class="gp">... </span> <span class="n">SomeClass</span><span class="o">.</span><span class="n">class_method</span><span class="p">(</span><span class="s">'bar'</span><span class="p">)</span> |
michael@0 | 503 | <span class="gp">... </span> <span class="k">return</span> <span class="n">mock1</span><span class="p">,</span> <span class="n">mock2</span> |
michael@0 | 504 | <span class="gp">...</span> |
michael@0 | 505 | <span class="gp">>>> </span><span class="n">mock1</span><span class="p">,</span> <span class="n">mock2</span> <span class="o">=</span> <span class="n">test</span><span class="p">()</span> |
michael@0 | 506 | <span class="gp">>>> </span><span class="n">mock1</span><span class="o">.</span><span class="n">assert_called_once_with</span><span class="p">(</span><span class="s">'foo'</span><span class="p">)</span> |
michael@0 | 507 | <span class="gp">>>> </span><span class="n">mock2</span><span class="o">.</span><span class="n">assert_called_once_with</span><span class="p">(</span><span class="s">'bar'</span><span class="p">)</span> |
michael@0 | 508 | </pre></div> |
michael@0 | 509 | </div> |
michael@0 | 510 | <p>Note that the decorators are applied from the bottom upwards. This is the |
michael@0 | 511 | standard way that Python applies decorators. The order of the created mocks |
michael@0 | 512 | passed into your test function matches this order.</p> |
michael@0 | 513 | <p>Like all context-managers patches can be nested using contextlib’s nested |
michael@0 | 514 | function; <em>every</em> patching will appear in the tuple after “as”:</p> |
michael@0 | 515 | <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">contextlib</span> <span class="kn">import</span> <span class="n">nested</span> |
michael@0 | 516 | <span class="gp">>>> </span><span class="k">with</span> <span class="n">nested</span><span class="p">(</span> |
michael@0 | 517 | <span class="gp">... </span> <span class="n">patch</span><span class="p">(</span><span class="s">'package.module.ClassName1'</span><span class="p">),</span> |
michael@0 | 518 | <span class="gp">... </span> <span class="n">patch</span><span class="p">(</span><span class="s">'package.module.ClassName2'</span><span class="p">)</span> |
michael@0 | 519 | <span class="gp">... </span> <span class="p">)</span> <span class="k">as</span> <span class="p">(</span><span class="n">MockClass1</span><span class="p">,</span> <span class="n">MockClass2</span><span class="p">):</span> |
michael@0 | 520 | <span class="gp">... </span> <span class="k">assert</span> <span class="n">package</span><span class="o">.</span><span class="n">module</span><span class="o">.</span><span class="n">ClassName1</span> <span class="ow">is</span> <span class="n">MockClass1</span> |
michael@0 | 521 | <span class="gp">... </span> <span class="k">assert</span> <span class="n">package</span><span class="o">.</span><span class="n">module</span><span class="o">.</span><span class="n">ClassName2</span> <span class="ow">is</span> <span class="n">MockClass2</span> |
michael@0 | 522 | <span class="gp">...</span> |
michael@0 | 523 | </pre></div> |
michael@0 | 524 | </div> |
michael@0 | 525 | </div> |
michael@0 | 526 | <div class="section" id="where-to-patch"> |
michael@0 | 527 | <span id="id1"></span><h2>Where to patch<a class="headerlink" href="#where-to-patch" title="Permalink to this headline">¶</a></h2> |
michael@0 | 528 | <p><cite>patch</cite> works by (temporarily) changing the object that a <em>name</em> points to with |
michael@0 | 529 | another one. There can be many names pointing to any individual object, so |
michael@0 | 530 | for patching to work you must ensure that you patch the name used by the system |
michael@0 | 531 | under test.</p> |
michael@0 | 532 | <p>The basic principle is that you patch where an object is <em>looked up</em>, which |
michael@0 | 533 | is not necessarily the same place as where it is defined. A couple of |
michael@0 | 534 | examples will help to clarify this.</p> |
michael@0 | 535 | <p>Imagine we have a project that we want to test with the following structure:</p> |
michael@0 | 536 | <div class="highlight-python"><pre>a.py |
michael@0 | 537 | -> Defines SomeClass |
michael@0 | 538 | |
michael@0 | 539 | b.py |
michael@0 | 540 | -> from a import SomeClass |
michael@0 | 541 | -> some_function instantiates SomeClass</pre> |
michael@0 | 542 | </div> |
michael@0 | 543 | <p>Now we want to test <cite>some_function</cite> but we want to mock out <cite>SomeClass</cite> using |
michael@0 | 544 | <cite>patch</cite>. The problem is that when we import module b, which we will have to |
michael@0 | 545 | do then it imports <cite>SomeClass</cite> from module a. If we use <cite>patch</cite> to mock out |
michael@0 | 546 | <cite>a.SomeClass</cite> then it will have no effect on our test; module b already has a |
michael@0 | 547 | reference to the <em>real</em> <cite>SomeClass</cite> and it looks like our patching had no |
michael@0 | 548 | effect.</p> |
michael@0 | 549 | <p>The key is to patch out <cite>SomeClass</cite> where it is used (or where it is looked up |
michael@0 | 550 | ). In this case <cite>some_function</cite> will actually look up <cite>SomeClass</cite> in module b, |
michael@0 | 551 | where we have imported it. The patching should look like:</p> |
michael@0 | 552 | <blockquote> |
michael@0 | 553 | <div><cite>@patch(‘b.SomeClass’)</cite></div></blockquote> |
michael@0 | 554 | <p>However, consider the alternative scenario where instead of <cite>from a import |
michael@0 | 555 | SomeClass</cite> module b does <cite>import a</cite> and <cite>some_function</cite> uses <cite>a.SomeClass</cite>. Both |
michael@0 | 556 | of these import forms are common. In this case the class we want to patch is |
michael@0 | 557 | being looked up on the a module and so we have to patch <cite>a.SomeClass</cite> instead:</p> |
michael@0 | 558 | <blockquote> |
michael@0 | 559 | <div><cite>@patch(‘a.SomeClass’)</cite></div></blockquote> |
michael@0 | 560 | </div> |
michael@0 | 561 | <div class="section" id="patching-descriptors-and-proxy-objects"> |
michael@0 | 562 | <h2>Patching Descriptors and Proxy Objects<a class="headerlink" href="#patching-descriptors-and-proxy-objects" title="Permalink to this headline">¶</a></h2> |
michael@0 | 563 | <p>Since version 0.6.0 both <a class="reference internal" href="#patch">patch</a> and <a class="reference internal" href="#patch-object">patch.object</a> have been able to correctly |
michael@0 | 564 | patch and restore descriptors: class methods, static methods and properties. |
michael@0 | 565 | You should patch these on the <em>class</em> rather than an instance.</p> |
michael@0 | 566 | <p>Since version 0.7.0 <a class="reference internal" href="#patch">patch</a> and <a class="reference internal" href="#patch-object">patch.object</a> work correctly with some objects |
michael@0 | 567 | that proxy attribute access, like the <a class="reference external" href="http://www.voidspace.org.uk/python/weblog/arch_d7_2010_12_04.shtml#e1198">django setttings object</a>.</p> |
michael@0 | 568 | <div class="admonition note"> |
michael@0 | 569 | <p class="first admonition-title">Note</p> |
michael@0 | 570 | <p class="last">In django <cite>import settings</cite> and <cite>from django.conf import settings</cite> |
michael@0 | 571 | return different objects. If you are using libraries / apps that do both you |
michael@0 | 572 | may have to patch both. Grrr...</p> |
michael@0 | 573 | </div> |
michael@0 | 574 | </div> |
michael@0 | 575 | </div> |
michael@0 | 576 | |
michael@0 | 577 | |
michael@0 | 578 | </div> |
michael@0 | 579 | </div> |
michael@0 | 580 | </div> |
michael@0 | 581 | <div class="sphinxsidebar"> |
michael@0 | 582 | <div class="sphinxsidebarwrapper"> |
michael@0 | 583 | <h3><a href="index.html">Table Of Contents</a></h3> |
michael@0 | 584 | <ul> |
michael@0 | 585 | <li><a class="reference internal" href="#">Patch Decorators</a><ul> |
michael@0 | 586 | <li><a class="reference internal" href="#patch">patch</a></li> |
michael@0 | 587 | <li><a class="reference internal" href="#patch-object">patch.object</a></li> |
michael@0 | 588 | <li><a class="reference internal" href="#patch-dict">patch.dict</a></li> |
michael@0 | 589 | <li><a class="reference internal" href="#patch-multiple">patch.multiple</a></li> |
michael@0 | 590 | <li><a class="reference internal" href="#patch-methods-start-and-stop">patch methods: start and stop</a></li> |
michael@0 | 591 | <li><a class="reference internal" href="#test-prefix">TEST_PREFIX</a></li> |
michael@0 | 592 | <li><a class="reference internal" href="#nesting-patch-decorators">Nesting Patch Decorators</a></li> |
michael@0 | 593 | <li><a class="reference internal" href="#where-to-patch">Where to patch</a></li> |
michael@0 | 594 | <li><a class="reference internal" href="#patching-descriptors-and-proxy-objects">Patching Descriptors and Proxy Objects</a></li> |
michael@0 | 595 | </ul> |
michael@0 | 596 | </li> |
michael@0 | 597 | </ul> |
michael@0 | 598 | |
michael@0 | 599 | <h4>Previous topic</h4> |
michael@0 | 600 | <p class="topless"><a href="mock.html" |
michael@0 | 601 | title="previous chapter">The Mock Class</a></p> |
michael@0 | 602 | <h4>Next topic</h4> |
michael@0 | 603 | <p class="topless"><a href="helpers.html" |
michael@0 | 604 | title="next chapter">Helpers</a></p> |
michael@0 | 605 | <h3>This Page</h3> |
michael@0 | 606 | <ul class="this-page-menu"> |
michael@0 | 607 | <li><a href="_sources/patch.txt" |
michael@0 | 608 | rel="nofollow">Show Source</a></li> |
michael@0 | 609 | </ul> |
michael@0 | 610 | <div id="searchbox" style="display: none"> |
michael@0 | 611 | <h3>Quick search</h3> |
michael@0 | 612 | <form class="search" action="search.html" method="get"> |
michael@0 | 613 | <input type="text" name="q" /> |
michael@0 | 614 | <input type="submit" value="Go" /> |
michael@0 | 615 | <input type="hidden" name="check_keywords" value="yes" /> |
michael@0 | 616 | <input type="hidden" name="area" value="default" /> |
michael@0 | 617 | </form> |
michael@0 | 618 | <p class="searchtip" style="font-size: 90%"> |
michael@0 | 619 | Enter search terms or a module, class or function name. |
michael@0 | 620 | </p> |
michael@0 | 621 | </div> |
michael@0 | 622 | <script type="text/javascript">$('#searchbox').show(0);</script> |
michael@0 | 623 | </div> |
michael@0 | 624 | </div> |
michael@0 | 625 | <div class="clearer"></div> |
michael@0 | 626 | </div> |
michael@0 | 627 | <div class="related"> |
michael@0 | 628 | <h3>Navigation</h3> |
michael@0 | 629 | <ul> |
michael@0 | 630 | <li class="right" style="margin-right: 10px"> |
michael@0 | 631 | <a href="genindex.html" title="General Index" |
michael@0 | 632 | >index</a></li> |
michael@0 | 633 | <li class="right" > |
michael@0 | 634 | <a href="helpers.html" title="Helpers" |
michael@0 | 635 | >next</a> |</li> |
michael@0 | 636 | <li class="right" > |
michael@0 | 637 | <a href="mock.html" title="The Mock Class" |
michael@0 | 638 | >previous</a> |</li> |
michael@0 | 639 | <li><a href="index.html">Mock 1.0.0 documentation</a> »</li> |
michael@0 | 640 | </ul> |
michael@0 | 641 | </div> |
michael@0 | 642 | <div class="footer"> |
michael@0 | 643 | © Copyright 2007-2012, Michael Foord & the mock team. |
michael@0 | 644 | Last updated on Oct 07, 2012. |
michael@0 | 645 | Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3. |
michael@0 | 646 | </div> |
michael@0 | 647 | </body> |
michael@0 | 648 | </html> |