0
0
FastapiHow-ToBeginner · 3 min read

How to Test File Upload in FastAPI: Simple Guide with Example

To test file upload in FastAPI, use TestClient from fastapi.testclient and send a POST request with the file data as files={'file': ('filename', file_bytes, 'content_type')}. This simulates uploading a file to your endpoint and lets you verify the response.
📐

Syntax

Testing file upload in FastAPI involves sending a POST request with a files parameter to the test client. The files parameter is a dictionary where the key is the form field name and the value is a tuple containing the filename, file content bytes, and the content type.

  • files={'file': ('filename', file_bytes, 'content_type')}: This simulates the file upload.
  • TestClient(app): Creates a test client for your FastAPI app.
  • client.post(url, files=files): Sends the POST request with the file.
python
from fastapi.testclient import TestClient

client = TestClient(app)

response = client.post(
    "/upload",
    files={"file": ("test.txt", b"file content", "text/plain")}
)
💻

Example

This example shows a FastAPI app with a file upload endpoint and a test that uploads a file using TestClient. The test checks if the upload was successful by asserting the response status and content.

python
from fastapi import FastAPI, File, UploadFile
from fastapi.testclient import TestClient

app = FastAPI()

@app.post("/upload")
async def upload_file(file: UploadFile = File(...)):
    content = await file.read()
    return {"filename": file.filename, "content_size": len(content)}

client = TestClient(app)

def test_upload_file():
    file_content = b"Hello, FastAPI file upload test!"
    response = client.post(
        "/upload",
        files={"file": ("hello.txt", file_content, "text/plain")}
    )
    assert response.status_code == 200
    json_resp = response.json()
    assert json_resp["filename"] == "hello.txt"
    assert json_resp["content_size"] == len(file_content)

# Run the test function
if __name__ == "__main__":
    test_upload_file()
    print("Test passed successfully.")
Output
Test passed successfully.
⚠️

Common Pitfalls

  • Forgetting to use files= in the test client POST request instead of data= causes the file not to be sent correctly.
  • Not providing the filename or content type in the tuple can lead to unexpected behavior.
  • Trying to read the file synchronously in the endpoint instead of using await file.read() when the endpoint is async.
  • Not using UploadFile type in the endpoint parameter, which is designed for file uploads.
python
from fastapi import FastAPI, File
from fastapi.testclient import TestClient

app = FastAPI()

# Wrong: Using bytes directly instead of UploadFile
@app.post("/upload_wrong")
def upload_wrong(file: bytes = File(...)):
    return {"size": len(file)}

client = TestClient(app)

# Wrong test: Using data= instead of files=
response_wrong = client.post("/upload_wrong", data={"file": ("test.txt", b"content")})

# Right test:
response_right = client.post(
    "/upload_wrong",
    files={"file": ("test.txt", b"content", "text/plain")}
)

assert response_right.status_code == 200
📊

Quick Reference

Remember these key points when testing file uploads in FastAPI:

  • Use TestClient to simulate requests.
  • Send files with the files= parameter as a dict with tuples.
  • Use UploadFile in your endpoint for efficient file handling.
  • Always include filename and content type in the test upload.

Key Takeaways

Use TestClient with the files parameter to simulate file uploads in tests.
Always send files as tuples with filename, bytes content, and content type.
Define your endpoint parameter as UploadFile for async file reading.
Avoid using data= instead of files= when posting files in tests.
Check response status and content to verify successful upload.