I’m trying to write unit tests for a FastAPI application that interacts with an SFTP server. Specifically, I’m having trouble mocking the SFTP client object to test the get_folder_structure function. Here’s a simplified version of my code:
import stat
from fastapi import APIRouter, HTTPException, Query, Depends
import paramiko
# Function to get SFTP client
def get_sftp_client():
try:
pkey = paramiko.RSAKey.from_private_key_file("C:/Users/User/Desktop/test_rsa.key")
transport = paramiko.Transport(("localhost", 3373))
transport.connect(username="admin", password="admin", pkey=pkey)
sftp = paramiko.SFTPClient.from_transport(transport)
return sftp
except Exception as e:
raise HTTPException(status_code=500, detail=f"Failed to connect to SFTP server: {str(e)}")
# Function to get folder structure
def get_folder_structure(sftp, folder_path="."):
folder_structure = {}
try:
for item in sftp.listdir_attr(folder_path):
item_path = os.path.join(folder_path, item.filename)
if stat.S_ISDIR(item.st_mode):
folder_structure[item.filename] = get_folder_structure(sftp, item_path)
else:
folder_structure[item.filename] = None
return folder_structure
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
# Route handler
@router.get("/folders")
def get_folders(sftp=Depends(get_sftp_client)):
try:
folder_structure = get_folder_structure(sftp)
sftp.close()
return {"folder_structure": folder_structure}
except Exception as e:
raise e
And here’s my attempt to mock the SFTP client in my unit tests:
from unittest.mock import MagicMock
from app.routers.six import get_folder_structure, get_sftp_client
@pytest.fixture
def mocked_sftp():
sftp = MagicMock()
sftp.listdir_attr.return_value = [
MagicMock(filename="folder1", st_mode=16877),
MagicMock(filename="file1.txt", st_mode=33188),
MagicMock(filename="folder2", st_mode=16877),
]
return sftp
def test_get_folder_structure_success(mocked_sftp):
sftp = get_sftp_client()
# Arrange
expected_structure = {
"folder1": {
"file1.txt": None,
},
"folder2": None,
}
actual_structure = get_folder_structure(mocked_sftp)
assert actual_structure == expected_structure
def test_get_folder_structure_exception(mocked_sftp):
# Arrange
mocked_sftp.listdir_attr.side_effect = Exception("Mocked exception")
# Act & Assert
with pytest.raises(Exception) as exc_info:
get_folder_structure(mocked_sftp)
assert str(exc_info.value) == "Mocked exception"
However, when I run these tests, I get an error indicating that the get_sftp_client function is not being mocked properly. How can I correctly mock the SFTP client in my unit tests to test the get_folder_structure function?
I’ve used the package sftpserver and you can run that via:
sftpserver -k “C:UsersUserDesktoptest_rsa.key” -l DEBUG
Thanks in advance for your help!