Files
payment-processing-test/tests/unit/test_lifecycle.py
T

90 lines
2.5 KiB
Python

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