Skip to content

Instantly share code, notes, and snippets.

@SebDeclercq
Created October 15, 2021 14:05
Show Gist options
  • Save SebDeclercq/dadbe35a489fd770ee5918ec1067c3d7 to your computer and use it in GitHub Desktop.
Save SebDeclercq/dadbe35a489fd770ee5918ec1067c3d7 to your computer and use it in GitHub Desktop.
from pathlib import Path
import ftplib
from pytest_mock import MockerFixture
import pytest
class FTPClient:
def __init__(self) -> None:
self.ftp: ftplib.FTP = ftplib.FTP()
def connect(self) -> bool:
return self.ftp.login().startswith('2')
def download(self, filename: str, file: Path) -> None:
try:
with file.open('wb') as handler:
self.ftp.retrbinary(f'RETR {filename}', handler.write)
except ftplib.error_perm as e:
file.unlink()
raise e
def test_connect_ok(mocker: MockerFixture) -> None:
mocker.patch('ftplib.FTP.__init__', return_value=None)
mocker.patch('ftplib.FTP.login', return_value='200')
ftp_client: FTPClient = FTPClient()
assert ftp_client.connect() is True
def test_connect_ko(mocker: MockerFixture) -> None:
mocker.patch('ftplib.FTP.__init__', return_value=None)
mocker.patch('ftplib.FTP.login', side_effect=ftplib.error_reply)
ftp_client: FTPClient = FTPClient()
with pytest.raises(ftplib.error_reply):
ftp_client.connect()
def test_retrbinary(mocker: MockerFixture, tmp_path: Path) -> None:
content: bytes = b'Hello World!'
mocker.patch('ftplib.FTP.__init__', return_value=None)
mocker.patch(
'ftplib.FTP.retrbinary',
side_effect=lambda _, callback: callback(content),
)
ftp_client: FTPClient = FTPClient()
file: Path = tmp_path / 'file.txt'
ftp_client.download('filename', file)
assert file.exists()
assert file.read_bytes() == content
def test_retrbinary_error_directory(mocker: MockerFixture) -> None:
mocker.patch('ftplib.FTP.__init__', return_value=None)
mocker.patch(
'ftplib.FTP.retrbinary',
side_effect=ftplib.error_perm('550 Failed to open file'),
)
ftp_client: FTPClient = FTPClient()
with pytest.raises(ftplib.error_perm, match='550'):
ftp_client.download('this_is_a_directory', Path('file.txt'))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment