Improved Homekit tests (#12800)

* Added test for temperature fahrenheit

* Restructured tests to use more mocks

* Rearanged homekit constants

* Improved 'test_homekit_class'

* Added import statements

* Fix Pylint Test errors
This commit is contained in:
cdce8p 2018-03-02 00:20:02 +01:00 committed by Paulus Schoutsen
parent d3386907a4
commit 168e1f0e2d
11 changed files with 420 additions and 94 deletions

View file

@ -64,12 +64,10 @@ def async_setup(hass, config):
def import_types():
"""Import all types from files in the HomeKit dir."""
"""Import all types from files in the HomeKit directory."""
_LOGGER.debug("Import type files.")
# pylint: disable=unused-variable
from .covers import Window # noqa F401
# pylint: disable=unused-variable
from .sensors import TemperatureSensor # noqa F401
from . import covers, sensors # noqa F401
def get_accessory(hass, state):

View file

@ -4,7 +4,7 @@ import logging
from pyhap.accessory import Accessory, Bridge, Category
from .const import (
SERV_ACCESSORY_INFO, MANUFACTURER,
SERV_ACCESSORY_INFO, SERV_BRIDGING_STATE, MANUFACTURER,
CHAR_MODEL, CHAR_MANUFACTURER, CHAR_SERIAL_NUMBER)
@ -46,17 +46,24 @@ def override_properties(char, new_properties):
class HomeAccessory(Accessory):
"""Class to extend the Accessory class."""
def __init__(self, display_name, model, category='OTHER'):
def __init__(self, display_name, model, category='OTHER', **kwargs):
"""Initialize a Accessory object."""
super().__init__(display_name)
super().__init__(display_name, **kwargs)
set_accessory_info(self, model)
self.category = getattr(Category, category, Category.OTHER)
def _set_services(self):
add_preload_service(self, SERV_ACCESSORY_INFO)
class HomeBridge(Bridge):
"""Class to extend the Bridge class."""
def __init__(self, display_name, model, pincode):
def __init__(self, display_name, model, pincode, **kwargs):
"""Initialize a Bridge object."""
super().__init__(display_name, pincode=pincode)
super().__init__(display_name, pincode=pincode, **kwargs)
set_accessory_info(self, model)
def _set_services(self):
add_preload_service(self, SERV_ACCESSORY_INFO)
add_preload_service(self, SERV_BRIDGING_STATE)

View file

@ -1,21 +1,24 @@
"""Constants used be the HomeKit component."""
MANUFACTURER = 'HomeAssistant'
# Service: AccessoryInfomation
# Services
SERV_ACCESSORY_INFO = 'AccessoryInformation'
CHAR_MODEL = 'Model'
CHAR_MANUFACTURER = 'Manufacturer'
CHAR_SERIAL_NUMBER = 'SerialNumber'
# Service: TemperatureSensor
SERV_BRIDGING_STATE = 'BridgingState'
SERV_TEMPERATURE_SENSOR = 'TemperatureSensor'
CHAR_CURRENT_TEMPERATURE = 'CurrentTemperature'
# Service: WindowCovering
SERV_WINDOW_COVERING = 'WindowCovering'
# Characteristics
CHAR_ACC_IDENTIFIER = 'AccessoryIdentifier'
CHAR_CATEGORY = 'Category'
CHAR_CURRENT_POSITION = 'CurrentPosition'
CHAR_TARGET_POSITION = 'TargetPosition'
CHAR_CURRENT_TEMPERATURE = 'CurrentTemperature'
CHAR_LINK_QUALITY = 'LinkQuality'
CHAR_MANUFACTURER = 'Manufacturer'
CHAR_MODEL = 'Model'
CHAR_POSITION_STATE = 'PositionState'
CHAR_REACHABLE = 'Reachable'
CHAR_SERIAL_NUMBER = 'SerialNumber'
CHAR_TARGET_POSITION = 'TargetPosition'
# Properties
PROP_CELSIUS = {'minValue': -273, 'maxValue': 999}

View file

@ -38,6 +38,9 @@ class Window(HomeAccessory):
get_characteristic(CHAR_TARGET_POSITION)
self.char_position_state = self.serv_cover. \
get_characteristic(CHAR_POSITION_STATE)
self.char_current_position.value = 0
self.char_target_position.value = 0
self.char_position_state.value = 0
self.char_target_position.setter_callback = self.move_cover

View file

@ -47,6 +47,7 @@ class TemperatureSensor(HomeAccessory):
self.char_temp = self.serv_temp. \
get_characteristic(CHAR_CURRENT_TEMPERATURE)
override_properties(self.char_temp, PROP_CELSIUS)
self.char_temp.value = 0
self.unit = None
def run(self):

View file

@ -0,0 +1,165 @@
"""Test all functions related to the basic accessory implementation.
This includes tests for all mock object types.
"""
from unittest.mock import patch
# pylint: disable=unused-import
from pyhap.loader import get_serv_loader, get_char_loader # noqa F401
from homeassistant.components.homekit.accessories import (
set_accessory_info, add_preload_service, override_properties,
HomeAccessory, HomeBridge)
from homeassistant.components.homekit.const import (
SERV_ACCESSORY_INFO, SERV_BRIDGING_STATE,
CHAR_MODEL, CHAR_MANUFACTURER, CHAR_SERIAL_NUMBER)
from tests.mock.homekit import (
get_patch_paths, mock_preload_service,
MockTypeLoader, MockAccessory, MockService, MockChar)
PATH_SERV = 'pyhap.loader.get_serv_loader'
PATH_CHAR = 'pyhap.loader.get_char_loader'
PATH_ACC, _ = get_patch_paths()
@patch(PATH_CHAR, return_value=MockTypeLoader('char'))
@patch(PATH_SERV, return_value=MockTypeLoader('service'))
def test_add_preload_service(mock_serv, mock_char):
"""Test method add_preload_service.
The methods 'get_serv_loader' and 'get_char_loader' are mocked.
"""
acc = MockAccessory('Accessory')
serv = add_preload_service(acc, 'TestService',
['TestChar', 'TestChar2'],
['TestOptChar', 'TestOptChar2'])
assert serv.display_name == 'TestService'
assert len(serv.characteristics) == 2
assert len(serv.opt_characteristics) == 2
acc.services = []
serv = add_preload_service(acc, 'TestService')
assert not serv.characteristics
assert not serv.opt_characteristics
acc.services = []
serv = add_preload_service(acc, 'TestService',
'TestChar', 'TestOptChar')
assert len(serv.characteristics) == 1
assert len(serv.opt_characteristics) == 1
assert serv.characteristics[0].display_name == 'TestChar'
assert serv.opt_characteristics[0].display_name == 'TestOptChar'
def test_override_properties():
"""Test override of characteristic properties with MockChar."""
char = MockChar('TestChar')
new_prop = {1: 'Test', 2: 'Demo'}
override_properties(char, new_prop)
assert char.properties == new_prop
def test_set_accessory_info():
"""Test setting of basic accessory information with MockAccessory."""
acc = MockAccessory('Accessory')
set_accessory_info(acc, 'model', 'manufacturer', '0000')
assert len(acc.services) == 1
serv = acc.services[0]
assert serv.display_name == SERV_ACCESSORY_INFO
assert len(serv.characteristics) == 3
chars = serv.characteristics
assert chars[0].display_name == CHAR_MODEL
assert chars[0].value == 'model'
assert chars[1].display_name == CHAR_MANUFACTURER
assert chars[1].value == 'manufacturer'
assert chars[2].display_name == CHAR_SERIAL_NUMBER
assert chars[2].value == '0000'
@patch(PATH_ACC, side_effect=mock_preload_service)
def test_home_accessory(mock_pre_serv):
"""Test initializing a HomeAccessory object."""
acc = HomeAccessory('TestAccessory', 'test.accessory', 'WINDOW')
assert acc.display_name == 'TestAccessory'
assert acc.category == 13 # Category.WINDOW
assert len(acc.services) == 1
serv = acc.services[0]
assert serv.display_name == SERV_ACCESSORY_INFO
char_model = serv.get_characteristic(CHAR_MODEL)
assert char_model.get_value() == 'test.accessory'
@patch(PATH_ACC, side_effect=mock_preload_service)
def test_home_bridge(mock_pre_serv):
"""Test initializing a HomeBridge object."""
bridge = HomeBridge('TestBridge', 'test.bridge', b'123-45-678')
assert bridge.display_name == 'TestBridge'
assert bridge.pincode == b'123-45-678'
assert len(bridge.services) == 2
assert bridge.services[0].display_name == SERV_ACCESSORY_INFO
assert bridge.services[1].display_name == SERV_BRIDGING_STATE
char_model = bridge.services[0].get_characteristic(CHAR_MODEL)
assert char_model.get_value() == 'test.bridge'
def test_mock_accessory():
"""Test attributes and functions of a MockAccessory."""
acc = MockAccessory('TestAcc')
serv = MockService('TestServ')
acc.add_service(serv)
assert acc.display_name == 'TestAcc'
assert len(acc.services) == 1
assert acc.get_service('TestServ') == serv
assert acc.get_service('NewServ').display_name == 'NewServ'
assert len(acc.services) == 2
def test_mock_service():
"""Test attributes and functions of a MockService."""
serv = MockService('TestServ')
char = MockChar('TestChar')
opt_char = MockChar('TestOptChar')
serv.add_characteristic(char)
serv.add_opt_characteristic(opt_char)
assert serv.display_name == 'TestServ'
assert len(serv.characteristics) == 1
assert len(serv.opt_characteristics) == 1
assert serv.get_characteristic('TestChar') == char
assert serv.get_characteristic('TestOptChar') == opt_char
assert serv.get_characteristic('NewChar').display_name == 'NewChar'
assert len(serv.characteristics) == 2
def test_mock_char():
"""Test attributes and functions of a MockChar."""
def callback_method(value):
"""Provide a callback options for 'set_value' method."""
assert value == 'With callback'
char = MockChar('TestChar')
char.set_value('Value')
assert char.display_name == 'TestChar'
assert char.get_value() == 'Value'
char.setter_callback = callback_method
char.set_value('With callback')

View file

@ -1,5 +1,6 @@
"""Test different accessory types: Covers."""
import unittest
from unittest.mock import patch
from homeassistant.core import callback
from homeassistant.components.cover import (
@ -10,6 +11,9 @@ from homeassistant.const import (
ATTR_SERVICE, ATTR_SERVICE_DATA, EVENT_CALL_SERVICE)
from tests.common import get_test_home_assistant
from tests.mock.homekit import get_patch_paths, mock_preload_service
PATH_ACC, PATH_FILE = get_patch_paths('covers')
class TestHomekitSensors(unittest.TestCase):
@ -35,13 +39,14 @@ class TestHomekitSensors(unittest.TestCase):
"""Test if accessory and HA are updated accordingly."""
window_cover = 'cover.window'
acc = Window(self.hass, window_cover, 'Cover')
acc.run()
with patch(PATH_ACC, side_effect=mock_preload_service):
with patch(PATH_FILE, side_effect=mock_preload_service):
acc = Window(self.hass, window_cover, 'Cover')
acc.run()
self.assertEqual(acc.char_current_position.value, 0)
self.assertEqual(acc.char_target_position.value, 0)
# Temporarily disabled due to bug in HAP-python==1.15 with py3.5
# self.assertEqual(acc.char_position_state.value, 0)
self.assertEqual(acc.char_position_state.value, 0)
self.hass.states.set(window_cover, STATE_UNKNOWN,
{ATTR_CURRENT_POSITION: None})
@ -49,8 +54,7 @@ class TestHomekitSensors(unittest.TestCase):
self.assertEqual(acc.char_current_position.value, 0)
self.assertEqual(acc.char_target_position.value, 0)
# Temporarily disabled due to bug in HAP-python==1.15 with py3.5
# self.assertEqual(acc.char_position_state.value, 0)
self.assertEqual(acc.char_position_state.value, 0)
self.hass.states.set(window_cover, STATE_OPEN,
{ATTR_CURRENT_POSITION: 50})

View file

@ -6,7 +6,7 @@ from homeassistant.components.homekit import (
TYPES, get_accessory, import_types)
from homeassistant.const import (
ATTR_UNIT_OF_MEASUREMENT, ATTR_SUPPORTED_FEATURES,
TEMP_CELSIUS, STATE_UNKNOWN)
TEMP_CELSIUS, TEMP_FAHRENHEIT, STATE_UNKNOWN)
def test_import_types():
@ -26,21 +26,32 @@ def test_component_not_supported():
assert True if get_accessory(None, state) is None else False
def test_sensor_temperatur_celsius():
"""Test temperature sensor with celsius as unit."""
def test_sensor_temperature_celsius():
"""Test temperature sensor with Celsius as unit."""
mock_type = MagicMock()
with patch.dict(TYPES, {'TemperatureSensor': mock_type}):
state = State('sensor.temperatur', '23',
state = State('sensor.temperature', '23',
{ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})
get_accessory(None, state)
assert len(mock_type.mock_calls) == 1
# pylint: disable=invalid-name
def test_sensor_temperature_fahrenheit():
"""Test temperature sensor with Fahrenheit as unit."""
mock_type = MagicMock()
with patch.dict(TYPES, {'TemperatureSensor': mock_type}):
state = State('sensor.temperature', '74',
{ATTR_UNIT_OF_MEASUREMENT: TEMP_FAHRENHEIT})
get_accessory(None, state)
assert len(mock_type.mock_calls) == 1
def test_cover_set_position():
"""Test cover with support for set_cover_position."""
mock_type = MagicMock()
with patch.dict(TYPES, {'Window': mock_type}):
state = State('cover.setposition', 'open',
state = State('cover.set_position', 'open',
{ATTR_SUPPORTED_FEATURES: 4})
get_accessory(None, state)
assert len(mock_type.mock_calls) == 1

View file

@ -1,20 +1,25 @@
"""Tests for the HomeKit component."""
import unittest
from unittest.mock import call, patch
from unittest.mock import call, patch, ANY
import voluptuous as vol
# pylint: disable=unused-import
from pyhap.accessory_driver import AccessoryDriver # noqa F401
from homeassistant import setup
from homeassistant.core import Event
from homeassistant.components.homekit import (
CONF_PIN_CODE, BRIDGE_NAME, HOMEKIT_FILE, HomeKit, valid_pin)
CONF_PIN_CODE, HOMEKIT_FILE, HomeKit, valid_pin)
from homeassistant.const import (
CONF_PORT, EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP)
from tests.common import get_test_home_assistant
from tests.mock.homekit import get_patch_paths, PATH_HOMEKIT
HOMEKIT_PATH = 'homeassistant.components.homekit'
PATH_ACC, _ = get_patch_paths()
IP_ADDRESS = '127.0.0.1'
CONFIG_MIN = {'homekit': {}}
CONFIG = {
@ -36,39 +41,6 @@ class TestHomeKit(unittest.TestCase):
"""Stop down everything that was started."""
self.hass.stop()
@patch(HOMEKIT_PATH + '.HomeKit.start_driver')
@patch(HOMEKIT_PATH + '.HomeKit.setup_bridge')
@patch(HOMEKIT_PATH + '.HomeKit.__init__')
def test_setup_min(self, mock_homekit, mock_setup_bridge,
mock_start_driver):
"""Test async_setup with minimal config option."""
mock_homekit.return_value = None
self.assertTrue(setup.setup_component(
self.hass, 'homekit', CONFIG_MIN))
mock_homekit.assert_called_once_with(self.hass, 51826)
mock_setup_bridge.assert_called_with(b'123-45-678')
mock_start_driver.assert_not_called()
self.hass.start()
self.hass.block_till_done()
self.assertEqual(mock_start_driver.call_count, 1)
@patch(HOMEKIT_PATH + '.HomeKit.start_driver')
@patch(HOMEKIT_PATH + '.HomeKit.setup_bridge')
@patch(HOMEKIT_PATH + '.HomeKit.__init__')
def test_setup_parameters(self, mock_homekit, mock_setup_bridge,
mock_start_driver):
"""Test async_setup with full config option."""
mock_homekit.return_value = None
self.assertTrue(setup.setup_component(
self.hass, 'homekit', CONFIG))
mock_homekit.assert_called_once_with(self.hass, 11111)
mock_setup_bridge.assert_called_with(b'987-65-432')
def test_validate_pincode(self):
"""Test async_setup with invalid config option."""
schema = vol.Schema(valid_pin)
@ -80,45 +52,64 @@ class TestHomeKit(unittest.TestCase):
for value in ('123-45-678', '234-56-789'):
self.assertTrue(schema(value))
@patch(PATH_HOMEKIT + '.HomeKit')
def test_setup_min(self, mock_homekit):
"""Test async_setup with minimal config option."""
self.assertTrue(setup.setup_component(
self.hass, 'homekit', CONFIG_MIN))
self.assertEqual(mock_homekit.mock_calls,
[call(self.hass, 51826),
call().setup_bridge(b'123-45-678')])
mock_homekit.reset_mock()
self.hass.bus.fire(EVENT_HOMEASSISTANT_START)
self.hass.block_till_done()
self.assertEqual(mock_homekit.mock_calls,
[call().start_driver(ANY)])
@patch(PATH_HOMEKIT + '.HomeKit')
def test_setup_parameters(self, mock_homekit):
"""Test async_setup with full config option."""
self.assertTrue(setup.setup_component(
self.hass, 'homekit', CONFIG))
self.assertEqual(mock_homekit.mock_calls,
[call(self.hass, 11111),
call().setup_bridge(b'987-65-432')])
@patch('pyhap.accessory_driver.AccessoryDriver')
@patch('pyhap.accessory.Bridge.add_accessory')
@patch(HOMEKIT_PATH + '.import_types')
@patch(HOMEKIT_PATH + '.get_accessory')
def test_homekit_pyhap_interaction(
self, mock_get_accessory, mock_import_types,
mock_add_accessory, mock_acc_driver):
def test_homekit_class(self, mock_acc_driver):
"""Test interaction between the HomeKit class and pyhap."""
mock_get_accessory.side_effect = ['TemperatureSensor', 'Window']
homekit = HomeKit(self.hass, 51826)
homekit.setup_bridge(b'123-45-678')
self.assertEqual(homekit.bridge.display_name, BRIDGE_NAME)
with patch(PATH_HOMEKIT + '.accessories.HomeBridge') as mock_bridge:
homekit = HomeKit(self.hass, 51826)
homekit.setup_bridge(b'123-45-678')
mock_bridge.reset_mock()
self.hass.states.set('demo.demo1', 'on')
self.hass.states.set('demo.demo2', 'off')
self.hass.start()
self.hass.block_till_done()
with patch('homeassistant.util.get_local_ip',
return_value='127.0.0.1'):
with patch(PATH_HOMEKIT + '.get_accessory') as mock_get_acc, \
patch(PATH_HOMEKIT + '.import_types') as mock_import_types, \
patch('homeassistant.util.get_local_ip') as mock_ip:
mock_get_acc.side_effect = ['TempSensor', 'Window']
mock_ip.return_value = IP_ADDRESS
homekit.start_driver(Event(EVENT_HOMEASSISTANT_START))
ip_address = '127.0.0.1'
path = self.hass.config.path(HOMEKIT_FILE)
self.assertEqual(mock_get_accessory.call_count, 2)
self.assertEqual(mock_import_types.call_count, 1)
self.assertEqual(mock_get_acc.call_count, 2)
self.assertEqual(mock_bridge.mock_calls,
[call().add_accessory('TempSensor'),
call().add_accessory('Window')])
self.assertEqual(mock_acc_driver.mock_calls,
[call(homekit.bridge, 51826, ip_address, path),
[call(homekit.bridge, 51826, IP_ADDRESS, path),
call().start()])
self.assertEqual(mock_add_accessory.mock_calls,
[call('TemperatureSensor'), call('Window')])
mock_acc_driver.reset_mock()
self.hass.bus.fire(EVENT_HOMEASSISTANT_STOP)
self.hass.block_till_done()
self.assertEqual(mock_acc_driver.mock_calls[2], call().stop())
self.assertEqual(len(mock_acc_driver.mock_calls), 3)
self.assertEqual(mock_acc_driver.mock_calls, [call().stop()])

View file

@ -1,12 +1,17 @@
"""Test different accessory types: Sensors."""
import unittest
from unittest.mock import patch
from homeassistant.components.homekit.const import PROP_CELSIUS
from homeassistant.components.homekit.sensors import (
TemperatureSensor, calc_temperature)
from homeassistant.const import (
ATTR_UNIT_OF_MEASUREMENT, TEMP_CELSIUS, TEMP_FAHRENHEIT, STATE_UNKNOWN)
from tests.common import get_test_home_assistant
from tests.mock.homekit import get_patch_paths, mock_preload_service
PATH_ACC, PATH_FILE = get_patch_paths('sensors')
def test_calc_temperature():
@ -27,19 +32,24 @@ class TestHomekitSensors(unittest.TestCase):
def setUp(self):
"""Setup things to be run when tests are started."""
self.hass = get_test_home_assistant()
get_patch_paths('sensors')
def tearDown(self):
"""Stop down everything that was started."""
self.hass.stop()
def test_temperature_celsius(self):
def test_temperature(self):
"""Test if accessory is updated after state change."""
temperature_sensor = 'sensor.temperature'
acc = TemperatureSensor(self.hass, temperature_sensor, 'Temperature')
acc.run()
with patch(PATH_ACC, side_effect=mock_preload_service):
with patch(PATH_FILE, side_effect=mock_preload_service):
acc = TemperatureSensor(self.hass, temperature_sensor,
'Temperature')
acc.run()
self.assertEqual(acc.char_temp.value, 0.0)
self.assertEqual(acc.char_temp.properties, PROP_CELSIUS)
self.hass.states.set(temperature_sensor, STATE_UNKNOWN,
{ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS})

133
tests/mock/homekit.py Normal file
View file

@ -0,0 +1,133 @@
"""Basic mock functions and objects related to the HomeKit component."""
PATH_HOMEKIT = 'homeassistant.components.homekit'
def get_patch_paths(name=None):
"""Return paths to mock 'add_preload_service'."""
path_acc = PATH_HOMEKIT + '.accessories.add_preload_service'
path_file = PATH_HOMEKIT + '.' + str(name) + '.add_preload_service'
return (path_acc, path_file)
def mock_preload_service(acc, service, chars=None, opt_chars=None):
"""Mock alternative for function 'add_preload_service'."""
service = MockService(service)
if chars:
chars = chars if isinstance(chars, list) else [chars]
for char_name in chars:
service.add_characteristic(char_name)
if opt_chars:
opt_chars = opt_chars if isinstance(opt_chars, list) else [opt_chars]
for opt_char_name in opt_chars:
service.add_characteristic(opt_char_name)
acc.add_service(service)
return service
class MockAccessory():
"""Define all attributes and methods for a MockAccessory."""
def __init__(self, name):
"""Initialize a MockAccessory object."""
self.display_name = name
self.services = []
def __repr__(self):
"""Return a representation of a MockAccessory. Use for debugging."""
serv_list = [serv.display_name for serv in self.services]
return "<accessory \"{}\", services={}>".format(
self.display_name, serv_list)
def add_service(self, service):
"""Add service to list of services."""
self.services.append(service)
def get_service(self, name):
"""Retrieve service from service list or return new MockService."""
for serv in self.services:
if serv.display_name == name:
return serv
serv = MockService(name)
self.add_service(serv)
return serv
class MockService():
"""Define all attributes and methods for a MockService."""
def __init__(self, name):
"""Initialize a MockService object."""
self.characteristics = []
self.opt_characteristics = []
self.display_name = name
def __repr__(self):
"""Return a representation of a MockService. Use for debugging."""
char_list = [char.display_name for char in self.characteristics]
opt_char_list = [
char.display_name for char in self.opt_characteristics]
return "<service \"{}\", chars={}, opt_chars={}>".format(
self.display_name, char_list, opt_char_list)
def add_characteristic(self, char):
"""Add characteristic to char list."""
self.characteristics.append(char)
def add_opt_characteristic(self, char):
"""Add characteristic to opt_char list."""
self.opt_characteristics.append(char)
def get_characteristic(self, name):
"""Get char for char lists or return new MockChar."""
for char in self.characteristics:
if char.display_name == name:
return char
for char in self.opt_characteristics:
if char.display_name == name:
return char
char = MockChar(name)
self.add_characteristic(char)
return char
class MockChar():
"""Define all attributes and methods for a MockChar."""
def __init__(self, name):
"""Initialize a MockChar object."""
self.display_name = name
self.properties = {}
self.value = None
self.type_id = None
self.setter_callback = None
def __repr__(self):
"""Return a representation of a MockChar. Use for debugging."""
return "<char \"{}\", value={}>".format(
self.display_name, self.value)
def set_value(self, value, should_notify=True, should_callback=True):
"""Set value of char."""
self.value = value
if self.setter_callback is not None and should_callback:
# pylint: disable=not-callable
self.setter_callback(value)
def get_value(self):
"""Get char value."""
return self.value
class MockTypeLoader():
"""Define all attributes and methods for a MockTypeLoader."""
def __init__(self, class_type):
"""Initialize a MockTypeLoader object."""
self.class_type = class_type
def get(self, name):
"""Return a MockService or MockChar object."""
if self.class_type == 'service':
return MockService(name)
elif self.class_type == 'char':
return MockChar(name)