0

When trying to test 2 or more functions in a single file using pytest in FastAPI, the following error occurs.

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
==================================================================== short test summary info =====================================================================
FAILED app/test/test_subscriptions.py::test_post_subscriptions - RuntimeError: Event loop is closed
============================================================ 1 failed, 1 passed, 16 warnings in 7.45s ============================================================

Here is the code at that time.

Here is the SetUp and TearDown processing:

class TestingSession(Session):
    def commit(self):
        self.flush()
        self.expire_all()


@pytest.fixture(scope="function")
def test_db():
    # Set Up
    TestSessionLocal = sessionmaker(
        class_=TestingSession,
        autocommit=False,
        autoflush=False,
        bind=engine
    )
    db = TestSessionLocal()

    def get_db_for_testing():
        try:
            yield db
            db.commit()
        except SQLAlchemyError as e:
            assert e is not None
            db.rollback()

    app.dependency_overrides[get_db] = get_db_for_testing

    # Test
    yield db

    # Tear Down
    db.rollback()
    close_all_sessions()
    engine.dispose()

These are the 2 test functions:

def test_read_subscriptions(test_db):
    test_team = test_db.query(Team).filter(
        Team.email == "unit_test_get@example.com"
    ).first()
    response = client.get(f'/api/v1/teams/{test_team.id}/subscriptions')
    assert response.status_code == 200

# intentionally duplicated the same function
def test_read_subscriptions_2(test_db):
    test_team = test_db.query(Team).filter(
        Team.email == "unit_test_get@example.com"
    ).first()
    response = client.get(f'/api/v1/teams/{test_team.id}/subscriptions')
    assert response.status_code == 200

This is the code for the middleware that is written in "main.py". When this is commented out, the test process works correctly.

@app.middleware("http")
async def log_middleware(request: Request, call_next):
    # create request ID
    request_id = str(uuid.uuid4())
    request.state.request_id = request_id

    logger = logging.getLogger("my_logger")

    is_not_develop_path = request.url.path not in ["/docs", "/openapi.json"]

    if is_not_develop_path:
        # request log
        logger.info(f"Request ID={request_id}, Method={request.method}, URL={request.url}")

    # calcurate processing time
    start_time = time.time()
    response = await call_next(request)
    process_time = time.time() - start_time

    if is_not_develop_path:
        # response log
        if 400 <= response.status_code < 600:
            # Log error if response status is 4xx or 5xx
            logger.error(f"Response ID={request_id}, Status={response.status_code}, ProcessTime={process_time}s")
        else:
            # Otherwise log info
            logger.info(f"Response ID={request_id}, Status={response.status_code}, ProcessTime={process_time}s")

    if is_not_develop_path:
        # write log to MongoDB
        await userLogsCrud.create_log(request=request)
    return response

Where the mistake would be?

I'm beginner in Python and don't have a good understanding in async IO!

I would appreciate it if you could let me know.

Dai
  • 3
  • 2
  • Looks like a duplicate of the following: https://stackoverflow.com/questions/45600579/asyncio-event-loop-is-closed-when-getting-loop . – N.K Jun 29 '23 at 14:45
  • Does this answer your question? ["Asyncio Event Loop is Closed" when getting loop](https://stackoverflow.com/questions/45600579/asyncio-event-loop-is-closed-when-getting-loop) – N.K Jun 29 '23 at 14:45

0 Answers0