Python 使用某个返回值模拟实例方法?
我有一个正在测试的方法,如下所示:Python 使用某个返回值模拟实例方法?,python,unit-testing,python-mock,Python,Unit Testing,Python Mock,我有一个正在测试的方法,如下所示: 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:
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
我正在尝试在unittest.TestCase测试方法中使用mock测试其对Popen的调用和对日志函数的调用:
最后一行出现以下故障:
stdout, stderr = p.communicate()
ValueError: need more than 0 values to unpack
我做错了什么?我有以下要求:
测试是否使用正确的值调用了subprocess.Popen的构造函数。
测试日志调用是否使用进程的输出和返回代码运行。
第二点很简单,我只是注入了一个MagicMock作为logger对象,但是我在第一点上遇到了问题。我认为主要的问题来自您的补丁对象:
@mock.patch.object(subprocess.Popen, 'communicate', autospec=True)
奇怪的是,似乎正在创建的模拟类型是:
<class 'unittest.mock.NonCallableMagicMock'>
因此,如您所见,我们基本上是根据mock_popen.return_值创建mock对象。从这里开始,所有其他内容都与您所做的工作非常一致。尝试在@mock.patch.object行中设置return\u值。尝试了,出现了相同的错误。正如错误中所说,您在return中捕获了两个值。。。因此,返回值必须是元组,例如0,0@NaftuliTzviKay我设法让它工作,但我的解决方案不包括使用@mock.patch.objectsubprocess.Popen,'communicate',autospec=True。我会把它贴出来看看是否有什么可以帮上忙的。我很想了解您的修补方法,以及为什么要修补测试模块中的subprocess.Popen和Popen?@idjaw如果可能的话,我想自动检查,以便我的对象的行为与现实生活中的Popen对象完全相同。
<class 'unittest.mock.NonCallableMagicMock'>
@mock.patch('server.upd.subprocess.Popen', autospec=True)
def test_fetch_metadata(self, mock_popen):
"""Test that we can fetch metadata correctly."""
mock_popen.return_value = Mock()
mock_popen_obj = mock_popen.return_value
mock_popen_obj.communicate.return_value = ("OUT", "ERR")
mock_popen_obj.returncode = 0
self.reference.execute_update()