Rework mysensors test fixtures (#67331)

* Reworks mysensors test fixtures

* Fix missing autospecced methods
This commit is contained in:
Martin Hjelmare 2022-03-02 07:23:36 +01:00 committed by GitHub
parent 4ea6ca7f91
commit e9496869da
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 57 additions and 31 deletions

View file

@ -4,7 +4,7 @@ from __future__ import annotations
from collections.abc import AsyncGenerator, Callable, Generator
import json
from typing import Any
from unittest.mock import MagicMock, patch
from unittest.mock import AsyncMock, MagicMock, patch
from mysensors import BaseSyncGateway
from mysensors.persistence import MySensorsJSONDecoder
@ -63,33 +63,44 @@ async def serial_transport_fixture(
"""Mock a serial transport."""
with patch(
"mysensors.gateway_serial.AsyncTransport", autospec=True
) as transport_class, patch("mysensors.AsyncTasks", autospec=True) as tasks_class:
tasks = tasks_class.return_value
tasks.persistence = MagicMock
) as transport_class, patch("mysensors.task.OTAFirmware", autospec=True), patch(
"mysensors.task.load_fw", autospec=True
), patch(
"mysensors.task.Persistence", autospec=True
) as persistence_class:
persistence = persistence_class.return_value
mock_gateway_features(tasks, transport_class, gateway_nodes)
mock_gateway_features(persistence, transport_class, gateway_nodes)
yield transport_class
def mock_gateway_features(
tasks: MagicMock, transport_class: MagicMock, nodes: dict[int, Sensor]
persistence: MagicMock, transport_class: MagicMock, nodes: dict[int, Sensor]
) -> None:
"""Mock the gateway features."""
async def mock_start_persistence() -> None:
async def mock_schedule_save_sensors() -> None:
"""Load nodes from via persistence."""
gateway = transport_class.call_args[0][0]
gateway.sensors.update(nodes)
tasks.start_persistence.side_effect = mock_start_persistence
persistence.schedule_save_sensors = AsyncMock(
side_effect=mock_schedule_save_sensors
)
# For some reason autospeccing does not recognize these methods.
persistence.safe_load_sensors = MagicMock()
persistence.save_sensors = MagicMock()
async def mock_start() -> None:
async def mock_connect() -> None:
"""Mock the start method."""
transport.connect_task = MagicMock()
gateway = transport_class.call_args[0][0]
gateway.on_conn_made(gateway)
tasks.start.side_effect = mock_start
transport = transport_class.return_value
transport.connect_task = None
transport.connect.side_effect = mock_connect
@pytest.fixture(name="transport")
@ -98,6 +109,12 @@ def transport_fixture(serial_transport: MagicMock) -> MagicMock:
return serial_transport
@pytest.fixture
def transport_write(transport: MagicMock) -> MagicMock:
"""Return the transport mock that accepts string messages."""
return transport.return_value.send
@pytest.fixture(name="serial_entry")
async def serial_entry_fixture(hass: HomeAssistant) -> MockConfigEntry:
"""Create a config entry for a serial gateway."""
@ -119,16 +136,28 @@ def config_entry_fixture(serial_entry: MockConfigEntry) -> MockConfigEntry:
return serial_entry
@pytest.fixture
async def integration(
@pytest.fixture(name="integration")
async def integration_fixture(
hass: HomeAssistant, transport: MagicMock, config_entry: MockConfigEntry
) -> AsyncGenerator[tuple[MockConfigEntry, Callable[[str], None]], None]:
) -> AsyncGenerator[MockConfigEntry, None]:
"""Set up the mysensors integration with a config entry."""
device = config_entry.data[CONF_DEVICE]
config: dict[str, Any] = {DOMAIN: {CONF_GATEWAYS: [{CONF_DEVICE: device}]}}
config_entry.add_to_hass(hass)
def receive_message(message_string: str) -> None:
with patch("homeassistant.components.mysensors.device.UPDATE_DELAY", new=0):
await async_setup_component(hass, DOMAIN, config)
await hass.async_block_till_done()
yield config_entry
@pytest.fixture
def receive_message(
transport: MagicMock, integration: MockConfigEntry
) -> Callable[[str], None]:
"""Receive a message for the gateway."""
def receive_message_callback(message_string: str) -> None:
"""Receive a message with the transport.
The message_string parameter is a string in the MySensors message format.
@ -137,14 +166,13 @@ async def integration(
# node_id;child_id;command;ack;type;payload\n
gateway.logic(message_string)
with patch("homeassistant.components.mysensors.device.UPDATE_DELAY", new=0):
await async_setup_component(hass, DOMAIN, config)
await hass.async_block_till_done()
yield config_entry, receive_message
return receive_message_callback
@pytest.fixture(name="gateway")
def gateway_fixture(transport, integration) -> BaseSyncGateway:
def gateway_fixture(
transport: MagicMock, integration: MockConfigEntry
) -> BaseSyncGateway:
"""Return a setup gateway."""
return transport.call_args[0][0]

View file

@ -1,8 +1,8 @@
"""Test function in __init__.py."""
from __future__ import annotations
from collections.abc import Callable
from typing import Any, Awaitable
from collections.abc import Awaitable, Callable
from typing import Any
from unittest.mock import patch
from aiohttp import ClientWebSocketResponse
@ -359,14 +359,14 @@ async def test_import(
async def test_remove_config_entry_device(
hass: HomeAssistant,
gps_sensor: Sensor,
integration: tuple[MockConfigEntry, Callable[[str], None]],
integration: MockConfigEntry,
gateway: BaseSyncGateway,
hass_ws_client: Callable[[HomeAssistant], Awaitable[ClientWebSocketResponse]],
) -> None:
"""Test that a device can be removed ok."""
entity_id = "sensor.gps_sensor_1_1"
node_id = 1
config_entry, _ = integration
config_entry = integration
assert await async_setup_component(hass, "config", {})
await hass.async_block_till_done()

View file

@ -29,11 +29,10 @@ from tests.common import MockConfigEntry
async def test_gps_sensor(
hass: HomeAssistant,
gps_sensor: Sensor,
integration: tuple[MockConfigEntry, Callable[[str], None]],
receive_message: Callable[[str], None],
) -> None:
"""Test a gps sensor."""
entity_id = "sensor.gps_sensor_1_1"
_, receive_message = integration
state = hass.states.get(entity_id)
@ -59,7 +58,7 @@ async def test_gps_sensor(
async def test_power_sensor(
hass: HomeAssistant,
power_sensor: Sensor,
integration: tuple[MockConfigEntry, Callable[[str], None]],
integration: MockConfigEntry,
) -> None:
"""Test a power sensor."""
entity_id = "sensor.power_sensor_1_1"
@ -76,7 +75,7 @@ async def test_power_sensor(
async def test_energy_sensor(
hass: HomeAssistant,
energy_sensor: Sensor,
integration: tuple[MockConfigEntry, Callable[[str], None]],
integration: MockConfigEntry,
) -> None:
"""Test an energy sensor."""
entity_id = "sensor.energy_sensor_1_1"
@ -93,7 +92,7 @@ async def test_energy_sensor(
async def test_sound_sensor(
hass: HomeAssistant,
sound_sensor: Sensor,
integration: tuple[MockConfigEntry, Callable[[str], None]],
integration: MockConfigEntry,
) -> None:
"""Test a sound sensor."""
entity_id = "sensor.sound_sensor_1_1"
@ -109,7 +108,7 @@ async def test_sound_sensor(
async def test_distance_sensor(
hass: HomeAssistant,
distance_sensor: Sensor,
integration: tuple[MockConfigEntry, Callable[[str], None]],
integration: MockConfigEntry,
) -> None:
"""Test a distance sensor."""
entity_id = "sensor.distance_sensor_1_1"
@ -129,14 +128,13 @@ async def test_distance_sensor(
async def test_temperature_sensor(
hass: HomeAssistant,
temperature_sensor: Sensor,
integration: tuple[MockConfigEntry, Callable[[str], None]],
receive_message: Callable[[str], None],
unit_system: UnitSystem,
unit: str,
) -> None:
"""Test a temperature sensor."""
entity_id = "sensor.temperature_sensor_1_1"
hass.config.units = unit_system
_, receive_message = integration
temperature = "22.0"
message_string = f"1;1;1;0;0;{temperature}\n"