使用 Pytest 测试 Asyncio:如何通过模拟事件循环来测试 try-except 块?

问题描述

在我正在使用的源代码(source link hereWIP PR here)中,我试图通过测试类“try-except”中的 __init__ 块来提高测试覆盖率方法。

从源码中剥离多余的代码,相关代码如下:

# webrtc.py

import asyncio
from loguru import logger
try:
    from asyncio import get_running_loop  # noqa Python >=3.7
except ImportError:  # pragma: no cover
    from asyncio.events import _get_running_loop as get_running_loop  # pragma: no cover

class WebRTCConnection:
    loop: Any

    def __init__(self) -> None:
        try:
            self.loop = get_running_loop()
        except RuntimeError as e:
            self.loop = None
            logger.error(e)
        
        if self.loop is None:
            self.loop = asyncio.new_event_loop()

在单独的测试文件中,我想模拟 RuntimeError 来测试 try except 块:

# webrtc_test.py

from unittest.mock import patch
from unittest.mock import Mock

import asyncio
import pytest
from webrtc import WebRTCConnection

@pytest.mark.asyncio
async def test_init_patch_runtime_error() -> None:
    nest_asyncio.apply()

    with patch("webrtc.get_running_loop",return_value=RuntimeError):
        with pytest.raises(RuntimeError):
            WebRTCConnection()

@pytest.mark.asyncio
async def test_init_mock_runtime_error() -> None:
    nest_asyncio.apply()

    mock_running_loop = Mock()
    mock_running_loop.side_effect = RuntimeError
    with patch("webrtc.get_running_loop",mock_running_loop):
        with pytest.raises(RuntimeError):
            domain = Domain(name="test")
            WebRTCConnection()

两个测试都不会通过,因为都不会引发 RuntimeError

此外,我尝试用 asyncio.new_event_loop 模拟 monkeypatch

# webrtc_test.py

from unittest.mock import patch
from unittest.mock import Mock

import asyncio
import pytest

from webrtc import WebRTCConnection

@pytest.mark.asyncio
async def test_init_new_event_loop(monkeypatch) -> None:
    nest_asyncio.apply()

    WebRTCConnection.loop = None
    mock_new_loop = Mock()
    monkeypatch.setattr(asyncio,"new_event_loop",mock_new_loop)
    WebRTCConnection()

    assert mock_new_loop.call_count == 1

这个测试也失败了,因为猴子补丁从来没有被调用过:> assert mock_new_loop.call_count == 1 E assert 0 == 1

我想知道我在这里做错了什么,我怎样才能成功测试这个类的 __init__ 方法?

非常感谢您的时间!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)