Skip to content

Commit

Permalink
refactor(MIXINS): rename module, standardize tests
Browse files Browse the repository at this point in the history
  • Loading branch information
niall-byrne committed Jan 15, 2024
1 parent a0a55f6 commit 3e599f6
Show file tree
Hide file tree
Showing 7 changed files with 205 additions and 140 deletions.
6 changes: 3 additions & 3 deletions pi_portal/modules/configuration/tests/test_user_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import pi_portal
import pytest
from pi_portal.modules.configuration import user_config
from pi_portal.modules.mixins import json_file
from pi_portal.modules.mixins import read_json_file

MOCK_INVALID_JSON = cast(user_config.TypeUserConfig, {"mock_setting": "0123"})
MOCK_VALID_JSON = cast(
Expand Down Expand Up @@ -71,15 +71,15 @@ def test_initialize__inheritance(
) -> None:
assert isinstance(
user_configuration_instance,
json_file.JSONFileReader,
read_json_file.JSONFileReader,
)

def test_load__calls_validate_and_sets_user_config(
self,
user_configuration_instance: user_config.UserConfiguration,
) -> None:
with mock.patch(
user_config.__name__ + ".json_file.JSONFileReader.load_json_file",
user_config.__name__ + ".read_json_file.JSONFileReader.load_json_file",
mock.Mock(return_value=MOCK_VALID_JSON)
):
with mock.patch.object(
Expand Down
4 changes: 2 additions & 2 deletions pi_portal/modules/configuration/user_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import pi_portal as root_module
from jsonschema.validators import validator_for
from pi_portal.modules.mixins import json_file
from pi_portal.modules.mixins import read_json_file
from typing_extensions import TypedDict


Expand Down Expand Up @@ -43,7 +43,7 @@ class UserConfigurationException(Exception):
"""Raised during validation of end user configuration."""


class UserConfiguration(json_file.JSONFileReader):
class UserConfiguration(read_json_file.JSONFileReader):
"""User configuration."""

validation_schema_path = (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""JSONFile mixin classes."""
"""JSONFileReader mixin class."""

import json
from pathlib import Path
Expand All @@ -17,6 +17,6 @@ def load_json_file(self, json_file_location: Union[Path, str]) -> Any:
:returns: The loaded JSON object.
"""

with open(json_file_location, encoding=self.encoding) as fhandle:
json_file_content = json.load(fhandle)
with open(json_file_location, encoding=self.encoding) as f_handle:
json_file_content = json.load(f_handle)
return json_file_content
93 changes: 85 additions & 8 deletions pi_portal/modules/mixins/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,97 @@
"""Test fixtures for the mixins modules tests."""
# pylint: disable=redefined-outer-name

from contextlib import closing
from io import BytesIO, StringIO
from unittest import mock

import pytest
from pi_portal.modules.configuration.tests.fixtures import mock_state
from .. import read_log_file
from .. import read_json_file, read_log_file, write_log_file


@pytest.fixture
def mocked_file_handle_binary() -> BytesIO:
return BytesIO()


@pytest.fixture
def mocked_file_handle_string() -> StringIO:
return StringIO()


@pytest.fixture
def mocked_get_logger() -> mock.Mock:
return mock.Mock()


@pytest.fixture
def mocked_json_logger() -> mock.Mock:
return mock.Mock()


@pytest.fixture
def mocked_open_read_binary(mocked_file_handle_binary: BytesIO) -> mock.Mock:
open_mock = mock.Mock()
open_mock.return_value = closing(mocked_file_handle_binary)
return open_mock

class ClassWithLoggingReader(read_log_file.LogFileReader):
"""A test class using the ReadLogFile mixin."""

@pytest.fixture
def mocked_open_read_string(mocked_file_handle_string: StringIO) -> mock.Mock:
open_mock = mock.Mock()
open_mock.return_value = closing(mocked_file_handle_string)
return open_mock


class LoggingReader(read_log_file.LogFileReader):
"""A test class using the LogFileReader mixin."""

logger_name = "test_logger"
log_file_path = "/var/run/some.log"


class LoggingWriter(write_log_file.LogFileWriter):
"""A test class using the LogFileWriter mixin."""

logger_name = "test_logger"
log_file_path = "/var/run/some.log"


@pytest.fixture
@mock_state.patch
def instance() -> ClassWithLoggingReader:
"""Test double for the temperature monitor logfile."""
def json_file_reader_instance(
monkeypatch: pytest.MonkeyPatch, mocked_open_read_string: StringIO
) -> read_json_file.JSONFileReader:
monkeypatch.setattr(
"builtins.open",
mocked_open_read_string,
)
return read_json_file.JSONFileReader()

return ClassWithLoggingReader()

@pytest.fixture
def log_file_reader_instance(
monkeypatch: pytest.MonkeyPatch,
mocked_open_read_binary: mock.Mock,
) -> read_log_file.LogFileReader:
monkeypatch.setattr(
"builtins.open",
mocked_open_read_binary,
)
return LoggingReader()


@pytest.fixture
def log_file_writer_instance(
mocked_get_logger: mock.Mock,
mocked_json_logger: mock.Mock,
monkeypatch: pytest.MonkeyPatch,
) -> write_log_file.LogFileWriter:
monkeypatch.setattr(
write_log_file.__name__ + ".getLogger",
mocked_get_logger,
)
monkeypatch.setattr(
write_log_file.__name__ + ".JsonLoggerConfiguration",
mocked_json_logger,
)
return LoggingWriter()
43 changes: 14 additions & 29 deletions pi_portal/modules/mixins/tests/test_json_file.py
Original file line number Diff line number Diff line change
@@ -1,45 +1,30 @@
"""Test the JSONFile mixin classes."""

import json
from unittest import TestCase, mock
from io import StringIO

from .. import json_file
from .. import read_json_file

JSON_FILE_MODULE = json_file.__name__


@mock.patch(JSON_FILE_MODULE + '.json')
@mock.patch('builtins.open')
class JSONFileReaderTest(TestCase):
class TestJSONFileReader:
"""Test the JSONFileReader mixin class."""

def setUp(self) -> None:
self.instance = json_file.JSONFileReader()
self.mock_object = {"mock": "object"}
self.mock_json = json.dumps(self.mock_object)
self.mock_context = mock.Mock()

def test_load_json_file_return_value(
def test__initialize__attributes(
self,
m_open: mock.Mock,
m_json: mock.Mock,
json_file_reader_instance: read_json_file.JSONFileReader,
) -> None:
mock_path = "/mock/path"
self.mock_context.return_value = self.mock_json
m_open.return_value.__enter__.return_value = self.mock_context
m_json.load.return_value = self.mock_object

result = self.instance.load_json_file(mock_path)
self.assertEqual(result, self.mock_object)
assert json_file_reader_instance.encoding == "utf-8"

def test_load_json_file_call(
def test__load_json_file__return_value(
self,
m_open: mock.Mock,
m_json: mock.Mock,
json_file_reader_instance: read_json_file.JSONFileReader,
mocked_file_handle_string: StringIO,
) -> None:
mock_path = "/mock/path"
m_open.return_value.__enter__.return_value = self.mock_context
mock_object = {"mock": "object"}
mocked_file_handle_string.write(json.dumps(mock_object))
mocked_file_handle_string.seek(0)

self.instance.load_json_file(mock_path)
result = json_file_reader_instance.load_json_file(mock_path)

m_json.load.assert_called_once_with(self.mock_context)
assert result == mock_object
Loading

0 comments on commit 3e599f6

Please sign in to comment.