1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Patch Decorators — Mock v0.6.0 documentation</title>
<link rel="stylesheet" href="_static/default.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
VERSION: '0.6.0',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="top" title="Mock v0.6.0 documentation" href="index.html" />
<link rel="next" title="Sentinel" href="sentinel.html" />
<link rel="prev" title="The Mock Class" href="mock.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="sentinel.html" title="Sentinel"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="mock.html" title="The Mock Class"
accesskey="P">previous</a> |</li>
<li><a href="index.html">Mock v0.6.0 documentation</a> »</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="patch-decorators">
<h1>Patch Decorators<a class="headerlink" href="#patch-decorators" title="Permalink to this headline">¶</a></h1>
<p>The patch decorators are used for patching objects only within the scope of the function they decorate. They automatically handle the unpatching for you, even if exceptions are raise. All of these functions can also be used in with statements.</p>
<div class="section" id="patch">
<h2>patch<a class="headerlink" href="#patch" title="Permalink to this headline">¶</a></h2>
<dl class="function">
<dt id="mock.patch">
<tt class="descname">patch</tt><big>(</big><em>target</em>, <em>new=None</em>, <em>spec=None</em>, <em>create=False</em><big>)</big><a class="headerlink" href="#mock.patch" title="Permalink to this definition">¶</a></dt>
<dd></dd></dl>
<p><tt class="docutils literal"><span class="pre">patch</span></tt> decorates a function. Inside the body of the function, the <tt class="docutils literal"><span class="pre">target</span></tt> (specified in the form ‘PackageName.ModuleName.ClassName’) is patched with a <tt class="docutils literal"><span class="pre">new</span></tt> object. When the function exits the patch is undone.</p>
<p>The target is imported and the specified attribute patched with the new object - so it must be importable from the environment you are calling the decorator from.</p>
<p>If <tt class="docutils literal"><span class="pre">new</span></tt> is omitted, then a new <tt class="docutils literal"><span class="pre">Mock</span></tt> is created and passed in as an extra argument to the decorated function:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="nd">@patch</span><span class="p">(</span><span class="s">'Package.ModuleName.ClassName'</span><span class="p">)</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> <span class="n">MockClass</span><span class="p">):</span>
<span class="s">"test something"</span>
</pre></div>
</div>
<p>The <tt class="docutils literal"><span class="pre">spec</span></tt> keyword argument is passed to the <tt class="docutils literal"><span class="pre">Mock</span></tt> if patch is creating one for you.</p>
<p>In addition you can pass <tt class="docutils literal"><span class="pre">spec=True</span></tt>, which causes patch to pass in the object being mocked as the spec object. If you are using patch to mock out a class, then the object you are interested in will probably be the return value of the Mock (the instance it returns when called). Because of this, if you use ‘spec=True’ and are patching a class (and having patch create a Mock for you) then the object being patched will be used as a spec for both the Mock <em>and</em> its return value.</p>
<p>Using the class as a spec object for the created Mock (and return value) means that the Mock will raise an exception if the code attempts to access any attributes that don’t exist.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="nd">@patch</span><span class="p">(</span><span class="s">'Package.ModuleName.ClassName'</span><span class="p">)</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> <span class="n">MockClass</span><span class="p">):</span>
<span class="n">instance</span> <span class="o">=</span> <span class="n">ClassName</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertRaises</span><span class="p">(</span><span class="ne">AttributeError</span><span class="p">,</span> <span class="k">lambda</span><span class="p">:</span> <span class="n">instance</span><span class="o">.</span><span class="n">fake_attribute</span><span class="p">)</span>
</pre></div>
</div>
<p>Patch can be used with the with statement - if this is available in your version of Python. Here the patching applies to the indented block after the with statement. Note that the patched object can always appear after the “as” - even if an object to be patched was specified, though it can be omitted.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">with</span> <span class="n">patch</span><span class="p">(</span><span class="s">'Package.ModuleName.ClassName'</span><span class="p">)</span> <span class="k">as</span> <span class="n">MockClass</span><span class="p">:</span>
<span class="n">instance</span> <span class="o">=</span> <span class="n">ClassName</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertRaises</span><span class="p">(</span><span class="ne">AttributeError</span><span class="p">,</span> <span class="k">lambda</span><span class="p">:</span> <span class="n">instance</span><span class="o">.</span><span class="n">fake_attribute</span><span class="p">)</span>
</pre></div>
</div>
<p>By default <tt class="docutils literal"><span class="pre">patch</span></tt> will fail to replace attributes that don’t exist. If you pass in ‘create=True’ and the attribute doesn’t exist, patch will create the attribute for you when the patched function is called, and delete it again afterwards. This is useful for writing tests against attributes that your production code creates at runtime. It is off by by default because it can be dangerous. With it switched on you can write passing tests against APIs that don’t actually exist!</p>
</div>
<div class="section" id="patch-object">
<h2>patch_object<a class="headerlink" href="#patch-object" title="Permalink to this headline">¶</a></h2>
<dl class="function">
<dt id="mock.patch_object">
<tt class="descname">patch_object</tt><big>(</big><em>target</em>, <em>attribute</em>, <em>new=None</em>, <em>spec=None</em>, <em>reate=False</em><big>)</big><a class="headerlink" href="#mock.patch_object" title="Permalink to this definition">¶</a></dt>
<dd><tt class="docutils literal"><span class="pre">patch_object</span></tt> patches named members on objects - usually class or module objects.</dd></dl>
<p>You can either call it with three arguments or two arguments. The three argument form takes the object to be patched, the attribute name and the object to replace the attribute with.</p>
<p>When calling with the two argument form you omit the replacement object, and a mock is created for you and passed in as an extra argument to the decorated function:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="nd">@patch_object</span><span class="p">(</span><span class="n">SomeClass</span><span class="p">,</span> <span class="s">'classmethod'</span><span class="p">)</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> <span class="n">mockMethod</span><span class="p">):</span>
<span class="n">SomeClass</span><span class="o">.</span><span class="n">classmethod</span><span class="p">(</span><span class="mf">3</span><span class="p">)</span>
<span class="n">mockMethod</span><span class="o">.</span><span class="n">assert_called_with</span><span class="p">(</span><span class="mf">3</span><span class="p">)</span>
</pre></div>
</div>
<p><tt class="docutils literal"><span class="pre">spec</span></tt> and <tt class="docutils literal"><span class="pre">create</span></tt> have the same meaning as for the patch decorator.</p>
<p><tt class="docutils literal"><span class="pre">patch_object</span></tt> is also a context manager and can be used with <tt class="docutils literal"><span class="pre">with</span></tt> statements in the same way
as <tt class="docutils literal"><span class="pre">patch</span></tt>.</p>
</div>
<div class="section" id="nesting-patch-decorators">
<h2>Nesting Patch Decorators<a class="headerlink" href="#nesting-patch-decorators" title="Permalink to this headline">¶</a></h2>
<p>If you want to perform multiple patches then you can simply stack up the decorators.</p>
<p>You can stack up multiple patch decorators using this pattern:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="nd">@patch</span><span class="p">(</span><span class="s">'module.ClassName1'</span><span class="p">)</span>
<span class="nd">@patch</span><span class="p">(</span><span class="s">'module.ClassName2'</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">testMethod</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">MockClass2</span><span class="p">,</span> <span class="n">MockClass1</span><span class="p">):</span>
<span class="n">ClassName1</span><span class="p">()</span>
<span class="n">ClassName2</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEquals</span><span class="p">(</span><span class="n">MockClass1</span><span class="o">.</span><span class="n">called</span><span class="p">,</span> <span class="s">"ClassName1 not patched"</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEquals</span><span class="p">(</span><span class="n">MockClass2</span><span class="o">.</span><span class="n">called</span><span class="p">,</span> <span class="s">"ClassName2 not patched"</span><span class="p">)</span>
</pre></div>
</div>
<p>Like all context-managers patches can be nested using contextlib’s nested function - <em>every</em> patching will appear in the tuple after “as”.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">contextlib</span> <span class="kn">import</span> <span class="n">nested</span>
<span class="k">with</span> <span class="n">nested</span><span class="p">(</span><span class="n">patch</span><span class="p">(</span><span class="s">'Package.ModuleName.ClassName'</span><span class="p">),</span>
<span class="n">patch</span><span class="p">(</span><span class="s">'Package.ModuleName.ClassName2'</span><span class="p">,</span> <span class="n">TestUtils</span><span class="o">.</span><span class="n">MockClass2</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>
<span class="n">instance</span> <span class="o">=</span> <span class="n">ClassName</span><span class="p">(</span><span class="n">ClassName2</span><span class="p">())</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEquals</span><span class="p">(</span><span class="n">instance</span><span class="o">.</span><span class="n">f</span><span class="p">(),</span> <span class="s">"expected"</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="patching-descriptors">
<h2>Patching Descriptors<a class="headerlink" href="#patching-descriptors" title="Permalink to this headline">¶</a></h2>
<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 patch and restore descriptors;
class methods, static methods and properties. You should patch these on the <em>class</em> rather than an instance:</p>
<div class="highlight-python"><pre>@patch('module.ClassName.static'):
def testMethod(self, mockStatic):
ClassName.static('foo')
mockStatic.assert_called_with('foo')</pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference external" href="">Patch Decorators</a><ul>
<li><a class="reference external" href="#patch">patch</a></li>
<li><a class="reference external" href="#patch-object">patch_object</a></li>
<li><a class="reference external" href="#nesting-patch-decorators">Nesting Patch Decorators</a></li>
<li><a class="reference external" href="#patching-descriptors">Patching Descriptors</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="mock.html"
title="previous chapter">The Mock Class</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="sentinel.html"
title="next chapter">Sentinel</a></p>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/patch.txt"
rel="nofollow">Show Source</a></li>
</ul>
<div id="searchbox" style="display: none">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip" style="font-size: 90%">
Enter search terms or a module, class or function name.
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="sentinel.html" title="Sentinel"
>next</a> |</li>
<li class="right" >
<a href="mock.html" title="The Mock Class"
>previous</a> |</li>
<li><a href="index.html">Mock v0.6.0 documentation</a> »</li>
</ul>
</div>
<div class="footer">
© Copyright 2009, Michael Foord.
Last updated on Aug 22, 2009.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.1.
</div>
</body>
</html>
|