<p>最近,我遇到了一个稍微复杂的问题,我用类似的方法解决了这个问题:为<code>mock.patch</code>中使用的mock设置<code>return_value</code>(如下所示)。在</p>
<p>通过使用<code>mock.patch</code>作为<a href="https://docs.python.org/3/library/unittest.mock.html#quick-guide" rel="nofollow noreferrer">context manager</a>(linked section中的Ctrl-F“with patch”代替decorator),可以进一步重构您的解决方案,使您能够更好地控制使用的对象:</p>
<pre class="lang-py prettyprint-override"><code>class TestFileRunner(unittest.TestCase):
def test_methodscalled(self):
id = 17
with mock.patch('FileRunner.ConfigB', return_value=Mock(Id=id)) as configB:
FileRunner().runProcess(1)
configB.assert_called_with(id)
</code></pre>
<h2>我的例子:断言调用是通过使用修补的对象实例进行的</h2>
<p>我想在一些类中测试条件日志(代码示例简化)。测试模块:</p>
^{pr2}$
<p>工作测试(解决问题后):</p>
<pre class="lang-py prettyprint-override"><code># test_module.py
from unittest import mock
import tested_module
class TestModule:
def test_exception_logged(self):
method_arguments = 1, 2, 3
logger_mock = mock.Mock()
tested_class_instance = mock.Mock(logger=logger_mock)
exception_mock_instance = mock.Mock()
with mock.patch.object(tested_module, 'CustomExceptionClass',
return_value=exception_mock_instance) as exception_mock:
tested_module.ClassUnderTest.tested_instance_method(tested_class_instance,
method_arguments)
logger_mock.exception.assert_called_once()
self.assertSequenceEqual(logger_mock.exception.call_args_list,
[mock.call(exception_mock_instance)])
exception_mock.assert_called_once()
self.assertSequenceEqual(exception_mock.call_args_list,
[mock.call(method_arguments)])
</code></pre>
<p>在我提出上述解决方案之前,有问题的部分是:</p>
<pre class="lang-py prettyprint-override"><code># Check below fails.
self.assertSequenceEqual(logger_mock.exception.call_args_list,
[mock.call(exception_mock)]) # Wrong object, "()" problem.
</code></pre>
<p>然后我试了一下:</p>
<pre class="lang-py prettyprint-override"><code>self.assertSequenceEqual(logger_mock.exception.call_args_list,
[mock.call(exception_mock())]) # Can't do `exception_mock()` ...
# ... because it was called 2nd time and assertion below will fail.
exception_mock.assert_called_once()
</code></pre>
<p>问题是,我必须以某种方式获取另一个模拟对象,当调用<code>exception_mock</code>时返回该对象,并且没有第二次调用<code>exception_mock</code>。因此,预先创建<code>mock.Mock</code>实例并分配给<code>return_value</code>是正确的答案。在</p>