When writing tests for Home Assistant integrations, mock external library dependencies rather than Home Assistant internals like coordinators, entities, or config entries. Test integration behavior through proper setup and service calls instead of directly manipulating internal objects.
When writing tests for Home Assistant integrations, mock external library dependencies rather than Home Assistant internals like coordinators, entities, or config entries. Test integration behavior through proper setup and service calls instead of directly manipulating internal objects.
What to mock:
What NOT to mock:
How to test:
config_entry.add_to_hass(hass)
and hass.config_entries.async_setup()
hass.services.async_call()
to simulate user interactionsExample:
# ❌ Don't mock HA internals
@pytest.fixture
def mock_coordinator():
coordinator = Mock(spec=MyDataUpdateCoordinator)
coordinator.data = {"device_1": {"state": "on"}}
return coordinator
# ✅ Mock external library instead
@pytest.fixture
def mock_api_client():
with patch("my_integration.MyAPIClient") as mock:
client = mock.return_value
client.get_devices.return_value = [{"id": "device_1", "state": "on"}]
client.set_device_state = AsyncMock()
yield client
# ✅ Test through service calls
async def test_turn_on_device(hass, mock_api_client, config_entry):
config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(config_entry.entry_id)
await hass.services.async_call(
"switch", "turn_on", {"entity_id": "switch.my_device"}, blocking=True
)
mock_api_client.set_device_state.assert_called_once_with("device_1", True)
This approach ensures tests verify actual integration behavior rather than implementation details, making them more robust and meaningful.
Enter the URL of a public GitHub repository