Refactor code structure for improved readability and maintainability
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
import asyncio
|
||||
from typing import Any
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
import pytest
|
||||
from fastapi import FastAPI
|
||||
|
||||
from app import main
|
||||
from app.config import Settings
|
||||
|
||||
|
||||
class FakeBroker:
|
||||
instance: "FakeBroker"
|
||||
|
||||
def __init__(self, *_: Any, **__: Any) -> None:
|
||||
type(self).instance = self
|
||||
self.started = False
|
||||
self.stopped = False
|
||||
|
||||
async def start(self) -> None:
|
||||
self.started = True
|
||||
|
||||
async def stop(self) -> None:
|
||||
self.stopped = True
|
||||
|
||||
|
||||
class CooperativePublisher:
|
||||
instance: "CooperativePublisher"
|
||||
|
||||
def __init__(self, *_: Any, **__: Any) -> None:
|
||||
type(self).instance = self
|
||||
self.stopped = False
|
||||
|
||||
async def run(self, stop_event: asyncio.Event) -> None:
|
||||
await stop_event.wait()
|
||||
self.stopped = True
|
||||
|
||||
|
||||
class StuckPublisher:
|
||||
instance: "StuckPublisher"
|
||||
|
||||
def __init__(self, *_: Any, **__: Any) -> None:
|
||||
type(self).instance = self
|
||||
self.cancelled = False
|
||||
|
||||
async def run(self, _: asyncio.Event) -> None:
|
||||
try:
|
||||
await asyncio.Event().wait()
|
||||
finally:
|
||||
self.cancelled = True
|
||||
|
||||
|
||||
async def test_lifespan_starts_and_stops_resources(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
declare_topology = AsyncMock()
|
||||
close_database = AsyncMock()
|
||||
monkeypatch.setattr(main, "RabbitBroker", FakeBroker)
|
||||
monkeypatch.setattr(main, "OutboxPublisher", CooperativePublisher)
|
||||
monkeypatch.setattr(main, "declare_topology", declare_topology)
|
||||
monkeypatch.setattr(main, "close_database", close_database)
|
||||
|
||||
async with main.lifespan(FastAPI()):
|
||||
assert FakeBroker.instance.started is True
|
||||
|
||||
assert CooperativePublisher.instance.stopped is True
|
||||
assert FakeBroker.instance.stopped is True
|
||||
declare_topology.assert_awaited_once_with(FakeBroker.instance)
|
||||
close_database.assert_awaited_once_with()
|
||||
|
||||
|
||||
async def test_lifespan_cancels_stuck_publisher(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
monkeypatch.setattr(main, "RabbitBroker", FakeBroker)
|
||||
monkeypatch.setattr(main, "OutboxPublisher", StuckPublisher)
|
||||
monkeypatch.setattr(main, "declare_topology", AsyncMock())
|
||||
monkeypatch.setattr(main, "close_database", AsyncMock())
|
||||
monkeypatch.setattr(
|
||||
main,
|
||||
"settings",
|
||||
Settings(outbox_publish_timeout=0.001, outbox_poll_interval=0.001),
|
||||
)
|
||||
|
||||
async with main.lifespan(FastAPI()):
|
||||
pass
|
||||
|
||||
assert StuckPublisher.instance.cancelled is True
|
||||
assert FakeBroker.instance.stopped is True
|
||||
Reference in New Issue
Block a user