vinissimus / async-asgi-testclient

A framework-agnostic library for testing ASGI web applications
MIT License
160 stars 20 forks source link

TestClient calls wrong methd when fastapi.APIRouter().add_api_router() is used to setup the router #62

Open johannes-mueller opened 1 year ago

johannes-mueller commented 1 year ago

TestClient always calls the GET routes, when routes are added using fastapi.APIRouter().add_api_router() no matter what method was requested.

Execute the following program

import asyncio
from async_asgi_testclient import TestClient as AsyncTestClient
from fastapi.testclient import TestClient

from fastapi import APIRouter, FastAPI

def get():
    print("called get", end=', ')

def post():
    print("called post", end=', ')

def put():
    print("called put", end=', ')

def delete():
    print("called delete", end=', ')

def make_router():
    router = APIRouter()
    router.add_api_route('/', get, methods=['GET'])
    router.add_api_route('/', post, methods=['POST'])
    router.add_api_route('/', put, methods=['PUT'])
    return router

api = FastAPI()
api.include_router(make_router(), prefix='/foo')

async def main():
    print("sync:")
    with TestClient(api) as client:
        print("GET request", client.get('/foo').status_code)
        print("POST request", client.post('/foo').status_code)
        print("PUT request", client.put('/foo').status_code)
        print("DELETE request", client.delete('/foo').status_code)
    print("async:")
    async with AsyncTestClient(api) as client:
        print("GET request", (await client.get('/foo')).status_code)
        print("POST request", (await client.post('/foo')).status_code)
        print("PUT request", (await client.put('/foo')).status_code)
        print("DELETE request", (await client.delete('/foo')).status_code)

asyncio.run(main())

output is

sync:
called get, GET request 200
called post, POST request 200
called put, PUT request 200
DELETE request 405
async:
called get, GET request 200
called get, POST request 200
called get, PUT request 200
called get, DELETE request 200

expected output is

sync:
called get, GET request 200
called post, POST request 200
called put, PUT request 200
DELETE request 405
async:
called get, GET request 200
called post, POST request 200
called put, PUT request 200
DELETE request 405

Python versions tested: 3.10, 3.11, 3.12 fastapi: 0.104.1 async-asgi-testclient: 1.4.11