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:
deadzilla 2026-05-31 12:34:29 +05:00
parent d12579b73c
commit 8cd1e48ede

View File

@ -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()