fix: устранить RuntimeWarning о не-awaited coroutine в тестах
- TestSchedulerInit: замокать tasks.loop через контекстный менеджер - TestSchedulerCalculateNextRun: добавить autouse fixture для патча tasks.loop - TestSchedulerStartStop: добавить autouse fixture для патча tasks.loop - test_run_morning_sends_embed: патчить fetch_weather/fetch_rss/fetch_cat напрямую вместо asyncio.gather, чтобы избежать не-awaited корутин
This commit is contained in:
parent
d12579b73c
commit
8cd1e48ede
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from unittest.mock import AsyncMock, MagicMock, patch
|
from unittest.mock import AsyncMock, MagicMock, patch, PropertyMock
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
import pytest
|
import pytest
|
||||||
@ -16,25 +16,37 @@ class TestSchedulerInit:
|
|||||||
def test_init_sets_morning_time(self):
|
def test_init_sets_morning_time(self):
|
||||||
"""Инициализация должна устанавливать время."""
|
"""Инициализация должна устанавливать время."""
|
||||||
bot = AsyncMock()
|
bot = AsyncMock()
|
||||||
scheduler = Scheduler(bot, "08:30")
|
mock_loop = MagicMock()
|
||||||
|
with patch("utils.morning_runner.tasks.loop", return_value=mock_loop):
|
||||||
|
scheduler = Scheduler(bot, "08:30")
|
||||||
assert scheduler.morning_time == "08:30"
|
assert scheduler.morning_time == "08:30"
|
||||||
|
|
||||||
def test_init_default_morning_time(self):
|
def test_init_default_morning_time(self):
|
||||||
"""Инициализация с дефолтным временем."""
|
"""Инициализация с дефолтным временем."""
|
||||||
bot = AsyncMock()
|
bot = AsyncMock()
|
||||||
scheduler = Scheduler(bot)
|
mock_loop = MagicMock()
|
||||||
|
with patch("utils.morning_runner.tasks.loop", return_value=mock_loop):
|
||||||
|
scheduler = Scheduler(bot)
|
||||||
assert scheduler.morning_time == "07:00"
|
assert scheduler.morning_time == "07:00"
|
||||||
|
|
||||||
def test_init_creates_loop(self):
|
def test_init_creates_loop(self):
|
||||||
"""Инициализация должна создавать loop."""
|
"""Инициализация должна создавать loop."""
|
||||||
bot = AsyncMock()
|
bot = AsyncMock()
|
||||||
scheduler = Scheduler(bot)
|
mock_loop = MagicMock()
|
||||||
|
with patch("utils.morning_runner.tasks.loop", return_value=mock_loop):
|
||||||
|
scheduler = Scheduler(bot)
|
||||||
assert scheduler.morning_loop is not None
|
assert scheduler.morning_loop is not None
|
||||||
|
|
||||||
|
|
||||||
class TestSchedulerCalculateNextRun:
|
class TestSchedulerCalculateNextRun:
|
||||||
"""Тесты расчёта следующего запуска."""
|
"""Тесты расчёта следующего запуска."""
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def _mock_loop(self):
|
||||||
|
"""Замокать tasks.loop, чтобы не создавать реальный coroutine."""
|
||||||
|
with patch("utils.morning_runner.tasks.loop", return_value=MagicMock()):
|
||||||
|
yield
|
||||||
|
|
||||||
def test_next_run_today_before_time(self):
|
def test_next_run_today_before_time(self):
|
||||||
"""Если сейчас раньше времени — вернуть сегодня."""
|
"""Если сейчас раньше времени — вернуть сегодня."""
|
||||||
bot = AsyncMock()
|
bot = AsyncMock()
|
||||||
@ -69,6 +81,12 @@ class TestSchedulerCalculateNextRun:
|
|||||||
class TestSchedulerStartStop:
|
class TestSchedulerStartStop:
|
||||||
"""Тесты запуска/остановки планировщика."""
|
"""Тесты запуска/остановки планировщика."""
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def _mock_loop(self):
|
||||||
|
"""Замокать tasks.loop, чтобы не создавать реальный coroutine."""
|
||||||
|
with patch("utils.morning_runner.tasks.loop", return_value=MagicMock()):
|
||||||
|
yield
|
||||||
|
|
||||||
def test_start_starts_loop(self):
|
def test_start_starts_loop(self):
|
||||||
"""start() должен вызывать start() на loop."""
|
"""start() должен вызывать start() на loop."""
|
||||||
bot = AsyncMock()
|
bot = AsyncMock()
|
||||||
@ -120,12 +138,18 @@ class TestRunMorning:
|
|||||||
channel.guild.me = MagicMock()
|
channel.guild.me = MagicMock()
|
||||||
channel.permissions_for.return_value.send_messages = True
|
channel.permissions_for.return_value.send_messages = True
|
||||||
|
|
||||||
with patch("utils.morning_runner.asyncio.gather", new=AsyncMock(return_value=(
|
weather_data = {
|
||||||
{"current_condition": [{"temp_C": "20", "FeelsLikeC": "22", "weatherDesc": [{"value": "Clear"}], "humidity": "50", "windspeedKmph": "10", "pressure": "1013"}]},
|
"current_condition": [
|
||||||
[{"title": "Test", "link": "http://test.com", "pub_date": "Mon, 01 Jan 2026 00:00:00 GMT", "creator": "", "tags": []}],
|
{"temp_C": "20", "FeelsLikeC": "22", "weatherDesc": [{"value": "Clear"}], "humidity": "50", "windspeedKmph": "10", "pressure": "1013"}
|
||||||
[{"title": "Test", "link": "http://test.com", "pub_date": "Mon, 01 Jan 2026 00:00:00 GMT", "creator": "", "tags": []}],
|
]
|
||||||
"http://cat.jpg",
|
}
|
||||||
))), patch("utils.morning_runner.discord.Embed") as mock_embed:
|
articles = [{"title": "Test", "link": "http://test.com", "pub_date": "Mon, 01 Jan 2026 00:00:00 GMT", "creator": "", "tags": []}]
|
||||||
|
posts = [{"title": "Test", "link": "http://test.com", "pub_date": "Mon, 01 Jan 2026 00:00:00 GMT", "creator": "", "tags": []}]
|
||||||
|
|
||||||
|
with patch("utils.morning_runner.fetch_weather", new=AsyncMock(return_value=weather_data)), \
|
||||||
|
patch("utils.morning_runner.fetch_rss", new=AsyncMock(side_effect=[articles, posts])), \
|
||||||
|
patch("utils.morning_runner.fetch_cat", new=AsyncMock(return_value="http://cat.jpg")), \
|
||||||
|
patch("utils.morning_runner.discord.Embed") as mock_embed:
|
||||||
await run_morning(bot, channel)
|
await run_morning(bot, channel)
|
||||||
|
|
||||||
channel.send.assert_called_once()
|
channel.send.assert_called_once()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user