Skip to content

Commit d2bb6d4

Browse files
committed
Allow passing the mocker in the constructor
This is to be able to call `start()` without any arguments, so we can make the `MockMicrogrid` an async context manager, to make sure it is properly finalized after it is used. Signed-off-by: Leandro Lucarella <[email protected]>
1 parent 69e93b7 commit d2bb6d4

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

tests/timeseries/mock_microgrid.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ def __init__( # pylint: disable=too-many-arguments
6262
num_namespaces: int = 1,
6363
fuse: Fuse | None = Fuse(Current.from_amperes(10_000.0)),
6464
graph: _MicrogridComponentGraph | None = None,
65+
mocker: MockerFixture | None = None,
6566
):
6667
"""Create a new instance.
6768
@@ -78,10 +79,12 @@ def __init__( # pylint: disable=too-many-arguments
7879
fuse: optional, the fuse to use for the grid connection.
7980
graph: optional, a graph of components to use instead of the default grid
8081
layout. If specified, grid_meter must be None.
82+
mocker: optional, a mocker to pass to the mock client and mock resampler.
8183
8284
Raises:
8385
ValueError: if both grid_meter and graph are specified.
8486
"""
87+
self._mocker = mocker
8588
if grid_meter is not None and graph is not None:
8689
raise ValueError("grid_meter and graph are mutually exclusive")
8790

@@ -163,9 +166,22 @@ def inverters(comp_type: InverterType) -> list[int]:
163166
self.meter_ids.append(self._grid_meter_id)
164167
self._start_meter_streaming(self._grid_meter_id)
165168

166-
async def start(self, mocker: MockerFixture) -> None:
169+
async def start(self, mocker: MockerFixture | None = None) -> None:
167170
"""Init the mock microgrid client and start the mock resampler."""
168-
self.init_mock_client(lambda mock_client: mock_client.initialize(mocker))
171+
# Return if it is already started
172+
if hasattr(self, "mock_client") or hasattr(self, "mock_resampler"):
173+
return
174+
175+
if mocker is None:
176+
mocker = self._mocker
177+
assert mocker is not None, "A mocker must be set at init or start time"
178+
179+
# This binding to a local is needed because Python uses late binding for
180+
# closures and `mocker` could be bound to `None` again after the lambda is
181+
# created. See:
182+
# https://mypy.readthedocs.io/en/stable/common_issues.html#narrowing-and-inner-functions
183+
local_mocker = mocker
184+
self.init_mock_client(lambda mock_client: mock_client.initialize(local_mocker))
169185
self.mock_resampler = MockResampler(
170186
mocker,
171187
ResamplerConfig(timedelta(seconds=self._sample_rate_s)),

0 commit comments

Comments
 (0)