aboutsummaryrefslogtreecommitdiffstats
path: root/tests/helpers.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/helpers.py')
-rw-r--r--tests/helpers.py46
1 files changed, 35 insertions, 11 deletions
diff --git a/tests/helpers.py b/tests/helpers.py
index 2b79a6c2a..2b176db79 100644
--- a/tests/helpers.py
+++ b/tests/helpers.py
@@ -4,12 +4,16 @@ import collections
import itertools
import logging
import unittest.mock
+from asyncio import AbstractEventLoop
from typing import Iterable, Optional
+import aioredis.abc
import discord
+from aiohttp import ClientSession
from discord.ext.commands import Context
from bot.api import APIClient
+from bot.async_stats import AsyncStatsClient
from bot.bot import Bot
@@ -264,10 +268,27 @@ class MockAPIClient(CustomMockMixin, unittest.mock.MagicMock):
spec_set = APIClient
-# Create a Bot instance to get a realistic MagicMock of `discord.ext.commands.Bot`
-bot_instance = Bot(command_prefix=unittest.mock.MagicMock())
-bot_instance.http_session = None
-bot_instance.api_client = None
+class MockRedisPool(CustomMockMixin, unittest.mock.MagicMock):
+ """
+ A MagicMock subclass to mock an aioredis connection pool.
+
+ Instances of this class will follow the specifications of `aioredis.abc.AbcPool` instances.
+ For more information, see the `MockGuild` docstring.
+ """
+ spec_set = aioredis.abc.AbcPool
+ additional_spec_asyncs = ("execute", "execute_pubsub")
+
+
+def _get_mock_loop() -> unittest.mock.Mock:
+ """Return a mocked asyncio.AbstractEventLoop."""
+ loop = unittest.mock.create_autospec(spec=AbstractEventLoop, spec_set=True)
+
+ # Since calling `create_task` on our MockBot does not actually schedule the coroutine object
+ # as a task in the asyncio loop, this `side_effect` calls `close()` on the coroutine object
+ # to prevent "has not been awaited"-warnings.
+ loop.create_task.side_effect = lambda coroutine: coroutine.close()
+
+ return loop
class MockBot(CustomMockMixin, unittest.mock.MagicMock):
@@ -277,17 +298,20 @@ class MockBot(CustomMockMixin, unittest.mock.MagicMock):
Instances of this class will follow the specifications of `discord.ext.commands.Bot` instances.
For more information, see the `MockGuild` docstring.
"""
- spec_set = bot_instance
- additional_spec_asyncs = ("wait_for",)
+ spec_set = Bot(command_prefix=unittest.mock.MagicMock(), loop=_get_mock_loop())
+ additional_spec_asyncs = ("wait_for", "_redis_ready")
def __init__(self, **kwargs) -> None:
super().__init__(**kwargs)
- self.api_client = MockAPIClient()
- # Since calling `create_task` on our MockBot does not actually schedule the coroutine object
- # as a task in the asyncio loop, this `side_effect` calls `close()` on the coroutine object
- # to prevent "has not been awaited"-warnings.
- self.loop.create_task.side_effect = lambda coroutine: coroutine.close()
+ self.loop = _get_mock_loop()
+ self.api_client = MockAPIClient(loop=self.loop)
+ self.http_session = unittest.mock.create_autospec(spec=ClientSession, spec_set=True)
+ self.stats = unittest.mock.create_autospec(spec=AsyncStatsClient, spec_set=True)
+
+ # fakeredis can't be used cause it'd require awaiting a coroutine to create the pool,
+ # which cannot be done here in __init__.
+ self.redis_session = MockRedisPool()
# Create a TextChannel instance to get a realistic MagicMock of `discord.TextChannel`