<p><a href="https://docs.python.org/3/library/unittest.mock.html#mock-open" rel="nofollow noreferrer">^{<cd1>}</a>是<a href="https://docs.python.org/3/library/unittest.mock.html#module-unittest.mock" rel="nofollow noreferrer">^{<cd2>}</a>框架的一部分,使用起来非常简单。<a href="https://docs.python.org/3/library/unittest.mock.html#patch" rel="nofollow noreferrer">^{<cd3>}</a>used as context返回用于替换已修补对象的对象:您可以使用它简化测试。</p>
<h2>Python3.x</h2>
<p>使用<code>builtins</code>而不是<code>__builtin__</code>。</p>
<pre><code>from unittest.mock import patch, mock_open
with patch("builtins.open", mock_open(read_data="data")) as mock_file:
assert open("path/to/open").read() == "data"
mock_file.assert_called_with("path/to/open")
</code></pre>
<h2>Python2.7</h2>
<p><code>mock</code>不是<code>unittest</code>的一部分,您应该修补<code>__builtin__</code></p>
<pre><code>from mock import patch, mock_open
with patch("__builtin__.open", mock_open(read_data="data")) as mock_file:
assert open("path/to/open").read() == "data"
mock_file.assert_called_with("path/to/open")
</code></pre>
<h2>装饰箱</h2>
<p>如果使用<code>patch</code>作为装饰符,使用<code>mock_open()</code>的结果作为<code>new</code><code>patch</code>的参数可能有点奇怪。</p>
<p>在这种情况下,最好使用<code>new_callable</code><code>patch</code>的参数,并记住<code>patch</code>不使用的每个额外参数都将传递给<code>new_callable</code>函数,如<a href="https://docs.python.org/3/library/unittest.mock.html#patch" rel="nofollow noreferrer">^{<cd3>} documentation</a>中所述。</p>
<blockquote>
<p>patch() takes arbitrary keyword arguments. These will be passed to the Mock (or new_callable) on construction.</p>
</blockquote>
<p>例如,Python 3.x的修饰版本是:</p>
<pre><code>@patch("builtins.open", new_callable=mock_open, read_data="data")
def test_patch(mock_file):
assert open("path/to/open").read() == "data"
mock_file.assert_called_with("path/to/open")
</code></pre>
<p>记住,在这种情况下,<code>patch</code>将添加mock对象作为测试函数的参数。</p>