Like ibrohim's answer , I prefer pytest with a mockery .
I went a little further and actually wrote a library that helps me mock easily. Here's how to use it in your case.
You start by having your own code and the basic pytest function, with the addition of my helper library for generating mock for modules and generating corresponding statements:
import ftplib from mock_autogen.pytest_mocker import PytestMocker def download_file(hostname, file_path, file_name): ftp = ftplib.FTP(hostname) ftp.login() ftp.cwd(file_path) def test_download_file(mocker): import sys print(PytestMocker(mocked=sys.modules[__name__], name=__name__).mock_modules().prepare_asserts_calls().generate()) download_file('ftp.server.local', 'pub/files', 'wanted_file.txt')
When you run the test for the first time, it will fail due to an unknown DNS, but the print statement that surrounds my library will give us such a valuable contribution:
... mock_ftplib = mocker.MagicMock(name='ftplib') mocker.patch('test_29817963.ftplib', new=mock_ftplib) ... import mock_autogen ... print(mock_autogen.generator.generate_asserts(mock_ftplib, name='mock_ftplib'))
I put this in a test and will run again:
def test_download_file(mocker): mock_ftplib = mocker.MagicMock(name='ftplib') mocker.patch('test_29817963.ftplib', new=mock_ftplib) download_file('ftp.server.local', 'pub/files', 'wanted_file.txt') import mock_autogen print(mock_autogen.generator.generate_asserts(mock_ftplib, name='mock_ftplib'))
This time the test was successful, and I only need to collect the result of the second fingerprint to get the correct statements:
def test_download_file(mocker): mock_ftplib = mocker.MagicMock(name='ftplib') mocker.patch(__name__ + .ftplib', new=mock_ftplib) download_file('ftp.server.local', 'pub/files', 'wanted_file.txt') mock_ftplib.FTP.assert_called_once_with('ftp.server.local') mock_ftplib.FTP.return_value.login.assert_called_once_with() mock_ftplib.FTP.return_value.cwd.assert_called_once_with('pub/files')
If you want to continue using unittest while using my library, I accept fetch requests .