简体   繁体   中英

testing paramiko in python3

I have a method thus:

def ftp_fetch(self, hostname=None, username=None, password=None, file_name=None):
        source_data = ''
        if hostname and username and password and file_name:
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            try:
                ssh.connect(hostname, username=username, password=password)
            except paramiko.SSHException:
                print("Connection Error")
            sftp = ssh.open_sftp()
            source_data = json.loads(
                sftp.file(file_name).read()
            )
            ssh.close()
            return source_data
        return False

... and a test thus:

@patch('paramiko.SSHClient')
def test_ftp_fetch(mock_ssh):
    test_content = '{"date": "06/02/2020", "time": "07:55", "floors":[{"floor": "地面", "capacity": 149, "occupancy": "20"},{"floor": "قبو", "capacity": 184, "occupancy": "20"}]}'
    mock_ssh.open_sftp().file().read().return_string = test_content
    foo = PreProcessor(code="foo")
    response = foo.ftp_fetch()
    assert response == False
    response = foo.ftp_fetch(hostname='http://foo/', username='foo', password = 'bar', file_name = 'baz')
   assert response == json.loads(test_content)

No matter what I've tried to do with the mock I get the same error:

___________________________________________________________________________ test_ftp_fetch ___________________________________________________________________________

mock_ssh = <MagicMock name='SSHClient' id='139650132358312'>

    @patch('paramiko.SSHClient')
    def test_ftp_fetch(mock_ssh):
        test_content = '{"date": "06/02/2020", "time": "07:55", "floors":[{"floor": "地面", "capacity": 149, "occupancy": "20"},{"floor": "قبو", "capacity": 184, "occupancy": "20"}]}'
        mock_ssh.open_sftp().file().read().return_string = test_content
        foo = PreProcessor(code="foo")
        response = foo.ftp_fetch()
        assert response == False
>       response = foo.ftp_fetch(hostname='http://foo/', username='foo', password = 'bar', file_name = 'baz')

preprocessors/test_preprocessors.py:339: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
preprocessors/preprocessors.py:229: in ftp_fetch
    sftp.file(file_name).read()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

s = <MagicMock name='SSHClient().open_sftp().file().read()' id='139650131723376'>, encoding = None, cls = None, object_hook = None, parse_float = None
parse_int = None, parse_constant = None, object_pairs_hook = None, kw = {}
<< snip lots of doc text >>
        if isinstance(s, str):
            if s.startswith('\ufeff'):
                raise JSONDecodeError("Unexpected UTF-8 BOM (decode using utf-8-sig)",
                                      s, 0)
        else:
            if not isinstance(s, (bytes, bytearray)):
                raise TypeError('the JSON object must be str, bytes or bytearray, '
>                               'not {!r}'.format(s.__class__.__name__))
E               TypeError: the JSON object must be str, bytes or bytearray, not 'MagicMock'

/usr/lib/python3.6/json/__init__.py:348: TypeError

So my question is simple:

How do I set up the mock so that the sftp read returns the text defined? (I'm using python 3.6 & pytest)

((and yes, I always try to test with high-order unicode text, even if I don't expect it in normal use))

  • Use the MonkeyPatch for better mocking.
  • Example:
def test_user_details(monkeypatch):
        mommy.make('Hallpass', user=user)
        return_data = 
            {
            'user_created':'done'
            }
        monkeypatch.setattr(
            'user.create_user', lambda *args, **kwargs: return_data)
        user_1 = create_user(user="+123456789")
        assert user_1.return_data == return_data

Pass monkeypatch as argument to the test and pass the desired method you want o mock on monkeypatch function on test with required return data as you need.

Make sure you install monkey patch pip install monkeypatch

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM