【发布时间】:2021-01-10 10:28:40
【问题描述】:
在我正在使用的源代码(source link here 和 WIP PR here)中,我试图通过在类的 __init__ 方法中测试 try-except 块来提高测试覆盖率。
从源码中去掉多余的代码,相关代码如下:
# 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。
另外,我尝试用monkeypatch模拟asyncio.new_event_loop:
# 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__ 方法?
非常感谢您的宝贵时间!
【问题讨论】:
标签: python pytest python-asyncio monkeypatching pytest-asyncio