Python模拟paramiko sftpclient打开

标签 python unit-testing mocking python-mock

我正在尝试模拟 paramiko SFTPClient.open() 并返回一个文件来测试我的文件解析代码。但是,当我如下设置模拟时,它返回一个 magicmock 实例,而不是打开的文件,其 _mock_return_value 等于打开的文件。

我希望 paramiko.SSHClient.open_sftp.open 等于打开的测试文件。我觉得这应该发生,但事实并非如此。我错过了什么吗?谁能解释一下,我做错了什么以及我是如何误解模拟的?

这是我的代码:

@app.route('/ipmivlan/<girls_name>', methods=['POST'])
def find_the_girl(girls_name):
  this_is_the_girl = None
  remote_file = None
  try:
    client = paramiko.SSHClient()
    # Auto add host key if not found/unknown
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    client.connect(host, username=username, password=password)
    sftp_client = client.open_sftp()
    remote_filename = '/usr/local/{0}'.format(girls_name.lower())
    remote_file = sftp_client.open(remote_filename, mode='r')
    print remote_file
    pprint(remote_file.__dict__)
    this_is_the_girl = parse_config(remote_file)
  except paramiko.ssh_exception.AuthenticationException:
    return_message = "Authentication has failed."
    app.logger.info(return_message)
    app.logger.info("Traceback: {0}".format(traceback.format_exc()))
    return jsonify(return_code=1, message=return_message, traceback=traceback.format_exc())
  except paramiko.ssh_exception.BadHostKeyException:
    return_message = "Server hostkey could not be verified"
    app.logger.info(return_message)
    app.logger.info("Traceback: {0}".format(traceback.format_exc()))
    return jsonify(return_code=1, message=return_message, traceback=traceback.format_exc())
  except paramiko.ssh_exception.SSHException:
    return_message = "Error connecting or establishing SSH Session."
    app.logger.info(return_message)
    app.logger.info("Traceback: {0}".format(traceback.format_exc()))
    return jsonify(return_code=1, message=return_message, traceback=traceback.format_exc())
  except paramiko.ssh_exception.socket.error:
    return_message = "Socket error occurred while connecting."
    app.logger.info(return_message)
    app.logger.info("Traceback: {0}".format(traceback.format_exc()))
    return jsonify(return_code=1, message=return_message, traceback=traceback.format_exc())
  except IOError:
    return_message = "IOError while trying to read remote file {0}".format(remote_filename)
    app.logger.info(return_message)
    app.logger.info("Traceback: {0}".format(traceback.format_exc()))
    return jsonify(return_code=1, message=return_message, traceback=traceback.format_exc())
  except: 
    return_message = "Unknown exception: {0}".format(str(sys.exc_info()[0]))
    app.logger.info(return_message)
    app.logger.info("Traceback: {0}".format(traceback.format_exc()))
    return jsonify(return_code=1, message=return_message, traceback=traceback.format_exc())
  finally:
    if remote_file is not None:
      remote_file.close()

if this_is_the_girl is None:
  return jsonify(return_code=0, message="Girl not found.")
elif this_is_the_girl == 'this is the girl:
  return jsonify(return_code=0, message="Successfully found girl")
elif this_is_the_girl == 'it's no longer your film, this is the girl.'
  return jsonify(return_code=50, message="GG no re.")


def parse_config(self, file):
  this_is_the_girl = None
  for line in file:
    # print line
    if re.findall('what girl, for what? what is this ray?', line):
      return "this is the girl"
    elif re.findall('that is considered one of the finest espressos in the world', line):
      return "it's no longer your film, this is the girl."

这是我的测试代码:

def setUp(self):
  self.test_file = open('this_is_the_girl_test_data.txt')

@mock.patch('src.mulholland.paramiko')
def test_find_girl(self, paramiko):
  expected_return_code = 0
  expected_message = "Successfully found girl"

  paramiko.SSHClient().open_sftp().open().return_value = self.test_file

  response = self.app.post('/mulholland_drive/{0}'.format(self.girl), data=dict(username=self.username, password=self.password), follow_redirects=True)
  response_json = json.loads(response.data)

  self.assertEqual(expected_return_code, response_json['return_code'])
  self.assertEqual(expected_message, response_json['message'])

def tearDown(self):
  self.test_file.close()

这是我的测试返回的结果:

<MagicMock name='paramiko.SSHClient().open_sftp().open()' id='4426176848'>
{'__str__': <MagicMock name='paramiko.SSHClient().open_sftp().open().__str__' id='4426525136'>,
 '_mock_call_args': None,
 '_mock_call_args_list': [],
 '_mock_call_count': 0,
 '_mock_called': False,
 '_mock_children': {'__str__': <MagicMock name='paramiko.SSHClient().open_sftp().open().__str__' id='4426525136'>},
 '_mock_delegate': None,
 '_mock_methods': None,
 '_mock_mock_calls': [call.__str__()],
 '_mock_name': None,
 '_mock_new_name': '()',
 '_mock_new_parent': <MagicMock name='paramiko.SSHClient().open_sftp().open' id='4426130896'>,
 '_mock_parent': None,
 '_mock_return_value': <open file 'this_is_the_girl_test_data.txt', mode 'r' at 0x107ab1930>,
 '_mock_side_effect': None,
 '_mock_unsafe': False,
 '_mock_wraps': None,
 '_spec_class': None,
 '_spec_set': None,
 '_spec_signature': None,
 'method_calls': []}

最佳答案

对于所有的关心,我已经弄清楚了。当我浏览这些行时,它返回一个可迭代对象,因此我实际上需要模拟 iter

paramiko.SSHClient().open_sftp().open().return_value = self.test_file

需要

paramiko.SSHClient().open_sftp().open().__iter__.return_value = self.test_file

关于Python模拟paramiko sftpclient打开,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36854720/

相关文章:

python - 在 Pandas 中,如果较小,如何将当前行项目设置为上一个?

spring - 如何使用 Dbunit 测试没有 Hibernate 实体的表的 Dao

unit-testing - 运行 Postman jetpack 测试以为 Newman 命令

ios - 如何在 Swift 中模拟 NSLocale.preferredLanguages 来测试请求?

reactjs - 未定义的“_isMockFunction”

java - Powermockito 私有(private)方法模拟 NullPointerException。调用私有(private)方法

java - 如何测试调用另一个类方法的方法?

python - 提取一组文本时如何使用正则表达式表示 "not"?

python - 如何迭代创建通用树的类属性?

python - 更改不在索引列表中的 NumPy 数组的值