Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 6 additions & 56 deletions tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -744,16 +744,12 @@ def mock_open_f(fname, **_):

def mock_coro(return_value=None, exception=None):
"""Return a coro that returns a value or raise an exception."""
return mock_coro_func(return_value, exception)()


def mock_coro_func(return_value=None, exception=None):
"""Return a method to create a coro function that returns a value."""

if exception:
return AsyncMock(side_effect=exception)

return AsyncMock(return_value=return_value)
fut = asyncio.Future()
if exception is not None:
fut.set_exception(exception)
else:
fut.set_result(return_value)
return fut


@contextmanager
Expand Down Expand Up @@ -838,52 +834,6 @@ async def get_restore_state_data() -> restore_state.RestoreStateData:
hass.data[key] = hass.async_create_task(get_restore_state_data())


class MockDependency:
"""Decorator to mock install a dependency."""

def __init__(self, root, *args):
"""Initialize decorator."""
self.root = root
self.submodules = args

def __enter__(self):
"""Start mocking."""

def resolve(mock, path):
"""Resolve a mock."""
if not path:
return mock

return resolve(getattr(mock, path[0]), path[1:])

base = MagicMock()
to_mock = {
f"{self.root}.{tom}": resolve(base, tom.split("."))
for tom in self.submodules
}
to_mock[self.root] = base

self.patcher = patch.dict("sys.modules", to_mock)
self.patcher.start()
return base

def __exit__(self, *exc):
"""Stop mocking."""
self.patcher.stop()
return False

def __call__(self, func):
"""Apply decorator."""

def run_mocked(*args, **kwargs):
"""Run with mocked dependencies."""
with self as base:
args = list(args) + [base]
func(*args, **kwargs)

return run_mocked


class MockEntity(entity.Entity):
"""Mock Entity class."""

Expand Down
6 changes: 3 additions & 3 deletions tests/components/alexa/test_smart_home.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""Test for smart home alexa support."""
from unittest.mock import patch

import pytest

Expand Down Expand Up @@ -39,7 +38,8 @@
reported_properties,
)

from tests.common import async_mock_service, mock_coro
from tests.async_mock import patch
from tests.common import async_mock_service


@pytest.fixture
Expand Down Expand Up @@ -3831,7 +3831,7 @@ async def test_initialize_camera_stream(hass, mock_camera, mock_stream):

with patch(
"homeassistant.components.demo.camera.DemoCamera.stream_source",
return_value=mock_coro("rtsp://example.local"),
return_value="rtsp://example.local",
), patch(
"homeassistant.helpers.network.async_get_external_url",
return_value="https://mycamerastream.test",
Expand Down
14 changes: 4 additions & 10 deletions tests/components/almond/test_init.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Tests for Almond set up."""
from time import time
from unittest.mock import patch

import pytest

Expand All @@ -10,7 +9,8 @@
from homeassistant.setup import async_setup_component
from homeassistant.util.dt import utcnow

from tests.common import MockConfigEntry, async_fire_time_changed, mock_coro
from tests.async_mock import patch
from tests.common import MockConfigEntry, async_fire_time_changed


@pytest.fixture(autouse=True)
Expand All @@ -34,7 +34,6 @@ async def test_set_up_oauth_remote_url(hass, aioclient_mock):

with patch(
"homeassistant.helpers.config_entry_oauth2_flow.async_get_config_entry_implementation",
return_value=mock_coro(),
):
assert await async_setup_component(hass, "almond", {})

Expand All @@ -43,9 +42,7 @@ async def test_set_up_oauth_remote_url(hass, aioclient_mock):
with patch("homeassistant.components.almond.ALMOND_SETUP_DELAY", 0), patch(
"homeassistant.helpers.network.async_get_external_url",
return_value="https://example.nabu.casa",
), patch(
"pyalmond.WebAlmondAPI.async_create_device", return_value=mock_coro()
) as mock_create_device:
), patch("pyalmond.WebAlmondAPI.async_create_device") as mock_create_device:
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
await hass.async_block_till_done()
async_fire_time_changed(hass, utcnow())
Expand All @@ -69,7 +66,6 @@ async def test_set_up_oauth_no_external_url(hass, aioclient_mock):

with patch(
"homeassistant.helpers.config_entry_oauth2_flow.async_get_config_entry_implementation",
return_value=mock_coro(),
), patch("pyalmond.WebAlmondAPI.async_create_device") as mock_create_device:
assert await async_setup_component(hass, "almond", {})

Expand Down Expand Up @@ -104,9 +100,7 @@ async def test_set_up_local(hass, aioclient_mock):
)
entry.add_to_hass(hass)

with patch(
"pyalmond.WebAlmondAPI.async_create_device", return_value=mock_coro()
) as mock_create_device:
with patch("pyalmond.WebAlmondAPI.async_create_device") as mock_create_device:
assert await async_setup_component(hass, "almond", {})

assert entry.state == config_entries.ENTRY_STATE_LOADED
Expand Down
23 changes: 9 additions & 14 deletions tests/components/asuswrt/test_device_tracker.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""The tests for the ASUSWRT device tracker platform."""
from unittest.mock import patch

from homeassistant.components.asuswrt import (
CONF_DNSMASQ,
Expand All @@ -10,13 +9,13 @@
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
from homeassistant.setup import async_setup_component

from tests.common import mock_coro_func
from tests.async_mock import AsyncMock, patch


async def test_password_or_pub_key_required(hass):
"""Test creating an AsusWRT scanner without a pass or pubkey."""
with patch("homeassistant.components.asuswrt.AsusWrt") as AsusWrt:
AsusWrt().connection.async_connect = mock_coro_func()
AsusWrt().connection.async_connect = AsyncMock()
AsusWrt().is_connected = False
result = await async_setup_component(
hass, DOMAIN, {DOMAIN: {CONF_HOST: "fake_host", CONF_USERNAME: "fake_user"}}
Expand All @@ -27,7 +26,7 @@ async def test_password_or_pub_key_required(hass):
async def test_network_unreachable(hass):
"""Test creating an AsusWRT scanner without a pass or pubkey."""
with patch("homeassistant.components.asuswrt.AsusWrt") as AsusWrt:
AsusWrt().connection.async_connect = mock_coro_func(exception=OSError)
AsusWrt().connection.async_connect = AsyncMock(side_effect=OSError)
AsusWrt().is_connected = False
result = await async_setup_component(
hass, DOMAIN, {DOMAIN: {CONF_HOST: "fake_host", CONF_USERNAME: "fake_user"}}
Expand All @@ -39,10 +38,8 @@ async def test_network_unreachable(hass):
async def test_get_scanner_with_password_no_pubkey(hass):
"""Test creating an AsusWRT scanner with a password and no pubkey."""
with patch("homeassistant.components.asuswrt.AsusWrt") as AsusWrt:
AsusWrt().connection.async_connect = mock_coro_func()
AsusWrt().connection.async_get_connected_devices = mock_coro_func(
return_value={}
)
AsusWrt().connection.async_connect = AsyncMock()
AsusWrt().connection.async_get_connected_devices = AsyncMock(return_value={})
result = await async_setup_component(
hass,
DOMAIN,
Expand All @@ -62,7 +59,7 @@ async def test_get_scanner_with_password_no_pubkey(hass):
async def test_specify_non_directory_path_for_dnsmasq(hass):
"""Test creating an AsusWRT scanner with a dnsmasq location which is not a valid directory."""
with patch("homeassistant.components.asuswrt.AsusWrt") as AsusWrt:
AsusWrt().connection.async_connect = mock_coro_func()
AsusWrt().connection.async_connect = AsyncMock()
AsusWrt().is_connected = False
result = await async_setup_component(
hass,
Expand All @@ -82,10 +79,8 @@ async def test_specify_non_directory_path_for_dnsmasq(hass):
async def test_interface(hass):
"""Test creating an AsusWRT scanner using interface eth1."""
with patch("homeassistant.components.asuswrt.AsusWrt") as AsusWrt:
AsusWrt().connection.async_connect = mock_coro_func()
AsusWrt().connection.async_get_connected_devices = mock_coro_func(
return_value={}
)
AsusWrt().connection.async_connect = AsyncMock()
AsusWrt().connection.async_get_connected_devices = AsyncMock(return_value={})
result = await async_setup_component(
hass,
DOMAIN,
Expand All @@ -106,7 +101,7 @@ async def test_interface(hass):
async def test_no_interface(hass):
"""Test creating an AsusWRT scanner using no interface."""
with patch("homeassistant.components.asuswrt.AsusWrt") as AsusWrt:
AsusWrt().connection.async_connect = mock_coro_func()
AsusWrt().connection.async_connect = AsyncMock()
AsusWrt().is_connected = False
result = await async_setup_component(
hass,
Expand Down
15 changes: 7 additions & 8 deletions tests/components/cast/test_init.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
"""Tests for the Cast config flow."""
from unittest.mock import patch

from homeassistant import config_entries, data_entry_flow
from homeassistant.components import cast
from homeassistant.setup import async_setup_component

from tests.common import MockDependency, mock_coro
from tests.async_mock import patch


async def test_creating_entry_sets_up_media_player(hass):
"""Test setting up Cast loads the media player."""
with patch(
"homeassistant.components.cast.media_player.async_setup_entry",
return_value=mock_coro(True),
) as mock_setup, MockDependency("pychromecast", "discovery"), patch(
return_value=True,
) as mock_setup, patch(
"pychromecast.discovery.discover_chromecasts", return_value=True
):
result = await hass.config_entries.flow.async_init(
Expand All @@ -34,8 +33,8 @@ async def test_creating_entry_sets_up_media_player(hass):
async def test_configuring_cast_creates_entry(hass):
"""Test that specifying config will create an entry."""
with patch(
"homeassistant.components.cast.async_setup_entry", return_value=mock_coro(True)
) as mock_setup, MockDependency("pychromecast", "discovery"), patch(
"homeassistant.components.cast.async_setup_entry", return_value=True
) as mock_setup, patch(
"pychromecast.discovery.discover_chromecasts", return_value=True
):
await async_setup_component(
Expand All @@ -49,8 +48,8 @@ async def test_configuring_cast_creates_entry(hass):
async def test_not_configuring_cast_not_creates_entry(hass):
"""Test that no config will not create an entry."""
with patch(
"homeassistant.components.cast.async_setup_entry", return_value=mock_coro(True)
) as mock_setup, MockDependency("pychromecast", "discovery"), patch(
"homeassistant.components.cast.async_setup_entry", return_value=True
) as mock_setup, patch(
"pychromecast.discovery.discover_chromecasts", return_value=True
):
await async_setup_component(hass, cast.DOMAIN, {})
Expand Down
5 changes: 2 additions & 3 deletions tests/components/cloud/__init__.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
"""Tests for the cloud component."""
from unittest.mock import patch

from homeassistant.components import cloud
from homeassistant.components.cloud import const
from homeassistant.setup import async_setup_component

from tests.common import mock_coro
from tests.async_mock import AsyncMock, patch


async def mock_cloud(hass, config=None):
"""Mock cloud."""
assert await async_setup_component(hass, cloud.DOMAIN, {"cloud": config or {}})
cloud_inst = hass.data["cloud"]
with patch("hass_nabucasa.Cloud.run_executor", return_value=mock_coro()):
with patch("hass_nabucasa.Cloud.run_executor", AsyncMock(return_value=None)):
await cloud_inst.start()


Expand Down
2 changes: 1 addition & 1 deletion tests/components/cloud/test_alexa_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def patch_sync_helper():
to_update = []
to_remove = []

async def sync_helper(to_upd, to_rem):
def sync_helper(to_upd, to_rem):
to_update.extend([ent_id for ent_id in to_upd if ent_id not in to_update])
to_remove.extend([ent_id for ent_id in to_rem if ent_id not in to_remove])
return True
Expand Down
9 changes: 3 additions & 6 deletions tests/components/cloud/test_client.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
"""Test the cloud.iot module."""
from unittest.mock import MagicMock, patch

from aiohttp import web
import pytest

Expand All @@ -12,8 +10,7 @@

from . import mock_cloud, mock_cloud_prefs

from tests.async_mock import AsyncMock
from tests.common import mock_coro
from tests.async_mock import AsyncMock, MagicMock, patch
from tests.components.alexa import test_smart_home as test_alexa


Expand Down Expand Up @@ -131,7 +128,7 @@ async def test_handler_google_actions_disabled(hass, mock_cloud_fixture):
"""Test handler Google Actions when user has disabled it."""
mock_cloud_fixture._prefs[PREF_ENABLE_GOOGLE] = False

with patch("hass_nabucasa.Cloud.start", return_value=mock_coro()):
with patch("hass_nabucasa.Cloud.start"):
assert await async_setup_component(hass, "cloud", {})

reqid = "5711642932632160983"
Expand All @@ -146,7 +143,7 @@ async def test_handler_google_actions_disabled(hass, mock_cloud_fixture):

async def test_webhook_msg(hass):
"""Test webhook msg."""
with patch("hass_nabucasa.Cloud.start", return_value=mock_coro()):
with patch("hass_nabucasa.Cloud.start"):
setup = await async_setup_component(hass, "cloud", {"cloud": {}})
assert setup
cloud = hass.data["cloud"]
Expand Down
Loading