【发布时间】:2016-04-08 00:00:15
【问题描述】:
我有一个正在测试的方法,如下所示:
def execute_update(self):
"""Execute an update."""
p = subprocess.Popen(['command'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
try:
stdout, stderr = p.communicate()
if p.returncode == 0:
# successful update, notify
self.logger.info("Successfully updated.")
else:
# failed update, notify
self.logger.error("Unable to update (code {returncode}):\n{output}".format(
returncode=p.returncode, output=stdout))
except KeyboardInterrupt as e:
# terminate the process
p.terminate()
raise e
我正在尝试使用mock 在unittest.TestCase 测试方法中测试它对 Popen 的调用及其对日志记录函数的调用:
@mock.patch.object(subprocess.Popen, 'communicate', autospec=True)
@mock.patch('updateservice.subprocess.Popen', autospec=True)
def test_fetch_metadata(self, mock_popen, mock_communicate):
"""Test that we can fetch metadata correctly."""
mock_communicate.return_value = ("OUT", "ERR")
mock_popen.returncode = 0
self.reference.execute_update()
# other asserts
最后一行失败:
stdout, stderr = p.communicate()
ValueError: need more than 0 values to unpack
我做错了什么?我有以下要求:
- 测试
subprocess.Popen的构造函数是否使用正确的值调用。 - 测试日志调用是否正在运行,并使用进程的输出和返回代码。
第二个很简单,我只是注入一个 MagicMock 作为记录器对象,但我遇到了第一个问题。
【问题讨论】:
-
尝试在
@mock.patch.object行中设置return_value。 -
试过了,同样的错误。
-
正如错误中所说,您在返回中捕获了两个值...因为您的 return_value 必须是一个元组,例如。 (0,0)
-
@NaftuliTzviKay 我设法让它工作,但我的解决方案不包括使用
@mock.patch.object(subprocess.Popen, 'communicate', autospec=True)。我会发布它,看看它是否有帮助。我很想了解您的修补方法以及为什么要在测试模块中同时修补subprocess.Popen和Popen? -
@idjaw 如果可能,我想自动指定,以便我的对象的行为与“现实生活”中的 Popen 对象完全一样。
标签: python unit-testing python-mock