完成渠道模块的单元测试目录搭建,新增多个领域模型、端口、中间件、事件、服务以及基础设施层的单元测试文件,同时补充了conftest.py的环境变量配置,完善测试基础环境。
90 lines
3.0 KiB
Python
90 lines
3.0 KiB
Python
from __future__ import annotations
|
|
|
|
from unittest.mock import AsyncMock, MagicMock
|
|
|
|
import pytest
|
|
|
|
from yuxi.channel.infrastructure.messaging.redis_pubsub_publisher import RedisPubSubPublisher
|
|
from yuxi.channel.infrastructure.messaging.redis_pubsub_subscriber import RedisPubSubSubscriber
|
|
|
|
|
|
class TestRedisPubSubPublisher:
|
|
@pytest.fixture
|
|
def mock_redis(self):
|
|
return AsyncMock()
|
|
|
|
@pytest.fixture
|
|
def publisher(self, mock_redis):
|
|
return RedisPubSubPublisher(redis=mock_redis)
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_publish(self, publisher, mock_redis):
|
|
await publisher.publish("test_event", {"data": "test"})
|
|
mock_redis.publish.assert_awaited_once()
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_publish_with_channel(self, publisher, mock_redis):
|
|
await publisher.publish("test_event", {"data": "test"}, channel="custom_channel")
|
|
mock_redis.publish.assert_awaited_once_with("custom_channel", '{"event_type": "test_event", "payload": {"data": "test"}}')
|
|
|
|
|
|
class TestRedisPubSubSubscriber:
|
|
@pytest.fixture
|
|
def mock_redis(self):
|
|
redis = AsyncMock()
|
|
pubsub = AsyncMock()
|
|
redis.pubsub.return_value = pubsub
|
|
return redis
|
|
|
|
@pytest.fixture
|
|
def subscriber(self, mock_redis):
|
|
return RedisPubSubSubscriber(redis=mock_redis)
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_subscribe(self, subscriber, mock_redis):
|
|
mock_redis.pubsub.return_value = AsyncMock()
|
|
await subscriber.subscribe("test_channel")
|
|
mock_redis.pubsub.return_value.subscribe.assert_awaited_once_with("test_channel")
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_unsubscribe(self, subscriber, mock_redis):
|
|
pubsub = AsyncMock()
|
|
subscriber._pubsub = pubsub
|
|
await subscriber.unsubscribe("test_channel")
|
|
pubsub.unsubscribe.assert_awaited_once_with("test_channel")
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_listen(self, subscriber, mock_redis):
|
|
pubsub = AsyncMock()
|
|
pubsub.listen.return_value = [
|
|
{"type": "message", "data": b'{"event_type": "test", "payload": {"data": "test"}}'}
|
|
]
|
|
subscriber._pubsub = pubsub
|
|
messages = []
|
|
async for msg in subscriber.listen():
|
|
messages.append(msg)
|
|
break
|
|
assert len(messages) == 1
|
|
assert messages[0]["event_type"] == "test"
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_listen_ignore_non_message(self, subscriber, mock_redis):
|
|
pubsub = AsyncMock()
|
|
pubsub.listen.return_value = [
|
|
{"type": "subscribe", "data": 1}
|
|
]
|
|
subscriber._pubsub = pubsub
|
|
messages = []
|
|
async for msg in subscriber.listen():
|
|
messages.append(msg)
|
|
break
|
|
assert len(messages) == 0
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_stop(self, subscriber, mock_redis):
|
|
pubsub = AsyncMock()
|
|
subscriber._pubsub = pubsub
|
|
await subscriber.stop()
|
|
pubsub.close.assert_awaited_once()
|
|
assert subscriber._running is False
|