From 60e0752f1ac4e5a5217c05dec23f62ce868a788c Mon Sep 17 00:00:00 2001 From: Ailitonia <41713304+Ailitonia@users.noreply.github.com> Date: Mon, 25 Sep 2023 11:02:50 +0800 Subject: [PATCH] =?UTF-8?q?:bug:=20Fix:=20bot.call=5Fapi=20=E5=9C=A8?= =?UTF-8?q?=E8=A2=AB=20called=20api=20hook=20mock=20=E5=90=8E=E5=BA=94?= =?UTF-8?q?=E8=AF=A5=E5=BF=BD=E7=95=A5=20exception=20(#2374)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ju4tCode <42488585+yanyongyu@users.noreply.github.com> --- nonebot/internal/adapter/bot.py | 3 + tests/test_adapters/test_bot.py | 152 ++++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 tests/test_adapters/test_bot.py diff --git a/nonebot/internal/adapter/bot.py b/nonebot/internal/adapter/bot.py index 8961b89f..3f827b18 100644 --- a/nonebot/internal/adapter/bot.py +++ b/nonebot/internal/adapter/bot.py @@ -106,7 +106,10 @@ class Bot(abc.ABC): logger.debug("Running CalledAPI hooks...") await asyncio.gather(*coros) except MockApiException as e: + # mock api result result = e.result + # ignore exception + exception = None logger.debug( f"Calling API {api} result is mocked. Return {result} instead." ) diff --git a/tests/test_adapters/test_bot.py b/tests/test_adapters/test_bot.py new file mode 100644 index 00000000..76571470 --- /dev/null +++ b/tests/test_adapters/test_bot.py @@ -0,0 +1,152 @@ +from typing import Any, Dict, Optional + +import pytest +from nonebug import App + +from nonebot.adapters import Bot +from nonebot.exception import MockApiException + + +@pytest.mark.asyncio +async def test_bot_call_api(app: App): + async with app.test_api() as ctx: + bot = ctx.create_bot() + ctx.should_call_api("test", {}, True) + result = await bot.call_api("test") + + assert result is True + + async with app.test_api() as ctx: + bot = ctx.create_bot() + ctx.should_call_api("test", {}, exception=RuntimeError("test")) + with pytest.raises(RuntimeError, match="test"): + await bot.call_api("test") + + +@pytest.mark.asyncio +async def test_bot_calling_api_hook_simple(app: App): + runned: bool = False + + async def calling_api_hook(bot: Bot, api: str, data: Dict[str, Any]): + nonlocal runned + runned = True + + hooks = set() + + with pytest.MonkeyPatch.context() as m: + m.setattr(Bot, "_calling_api_hook", hooks) + + Bot.on_calling_api(calling_api_hook) + + assert hooks == {calling_api_hook} + + async with app.test_api() as ctx: + bot = ctx.create_bot() + ctx.should_call_api("test", {}, True) + result = await bot.call_api("test") + + assert runned is True + assert result is True + + +@pytest.mark.asyncio +async def test_bot_calling_api_hook_mock(app: App): + runned: bool = False + + async def calling_api_hook(bot: Bot, api: str, data: Dict[str, Any]): + nonlocal runned + runned = True + + raise MockApiException(False) + + hooks = set() + + with pytest.MonkeyPatch.context() as m: + m.setattr(Bot, "_calling_api_hook", hooks) + + Bot.on_calling_api(calling_api_hook) + + assert hooks == {calling_api_hook} + + async with app.test_api() as ctx: + bot = ctx.create_bot() + result = await bot.call_api("test") + + assert runned is True + assert result is False + + +@pytest.mark.asyncio +async def test_bot_called_api_hook_simple(app: App): + runned: bool = False + + async def called_api_hook( + bot: Bot, + exception: Optional[Exception], + api: str, + data: Dict[str, Any], + result: Any, + ): + nonlocal runned + runned = True + + hooks = set() + + with pytest.MonkeyPatch.context() as m: + m.setattr(Bot, "_called_api_hook", hooks) + + Bot.on_called_api(called_api_hook) + + assert hooks == {called_api_hook} + + async with app.test_api() as ctx: + bot = ctx.create_bot() + ctx.should_call_api("test", {}, True) + result = await bot.call_api("test") + + assert runned is True + assert result is True + + +@pytest.mark.asyncio +async def test_bot_called_api_hook_mock(app: App): + runned: bool = False + + async def called_api_hook( + bot: Bot, + exception: Optional[Exception], + api: str, + data: Dict[str, Any], + result: Any, + ): + nonlocal runned + runned = True + + raise MockApiException(False) + + hooks = set() + + with pytest.MonkeyPatch.context() as m: + m.setattr(Bot, "_called_api_hook", hooks) + + Bot.on_called_api(called_api_hook) + + assert hooks == {called_api_hook} + + async with app.test_api() as ctx: + bot = ctx.create_bot() + ctx.should_call_api("test", {}, True) + result = await bot.call_api("test") + + assert runned is True + assert result is False + + runned = False + + async with app.test_api() as ctx: + bot = ctx.create_bot() + ctx.should_call_api("test", {}, exception=RuntimeError("test")) + result = await bot.call_api("test") + + assert runned is True + assert result is False